//
using System;
using System.Collections;
+using System.Collections.Specialized;
using System.Configuration;
+using System.Threading;
#if (XML_DEP)
using System.Xml;
#endif
{
internal sealed class DiagnosticsConfiguration
{
- private static IDictionary settings =
- (IDictionary) ConfigurationSettings.GetConfig ("system.diagnostics");
+#if NO_LOCK_FREE
+ private static object lock_ = new object();
+#endif
+ private static object settings;
public static IDictionary Settings {
get {
- return settings;
+#if !NO_LOCK_FREE
+ if (settings == null) {
+ object s = ConfigurationSettings.GetConfig ("system.diagnostics");
+ if (s == null)
+ throw new Exception ("INTERNAL configuration error: failed to get configuration 'system.diagnostics'");
+ Thread.MemoryBarrier ();
+ while (Interlocked.CompareExchange (ref settings, s, null) == null) {
+ // do nothing; we're just setting settings.
+ }
+ Thread.MemoryBarrier ();
+ }
+#else
+ lock (lock_) {
+ if (settings == null)
+ settings = ConfigurationSettings.GetConfig ("system.diagnostics");
+ }
+#endif
+ return (IDictionary) settings;
}
}
}
elementHandlers ["assert"] = new ElementHandler (AddAssertNode);
elementHandlers ["switches"] = new ElementHandler (AddSwitchesNode);
elementHandlers ["trace"] = new ElementHandler (AddTraceNode);
+#if NET_2_0
+ elementHandlers ["sources"] = new ElementHandler (AddSourcesNode);
+#endif
}
public virtual object Create (object parent, object configContext, XmlNode section)
case "add":
name = GetAttribute (attributes, "name", true, child);
value = GetAttribute (attributes, "value", true, child);
- newNodes[name] = AsString (value);
+ value = AsString (value); ValidateIntegralValue (name, value);
+ newNodes [name] = value;
break;
case "remove":
name = GetAttribute (attributes, "name", true, child);
d [node.Name] = newNodes;
}
+ private static int ValidateIntegralValue (string name, string value)
+ {
+ try {
+ return int.Parse (value);
+ } catch {
+ throw new ConfigurationException (string.Format (
+ "Error in '{0}': " +
+ "The value of a switch must be integral", name));
+ }
+ }
+
private void AddTraceNode (IDictionary d, XmlNode node)
{
AddTraceAttributes (d, node);
d ["indentsize"] = n;
TraceImpl.IndentSize = n;
}
+ catch (ConfigurationException e) {
+ throw;
+ }
catch (Exception e) {
throw new ConfigurationException ("The `indentsize' attribute must be an integral value.",
e, node);
}
}
+#if NET_2_0
+ static readonly Hashtable static_sources = new Hashtable ();
+
+ private void AddSourcesNode (IDictionary d, XmlNode node)
+ {
+ // FIXME: are there valid attributes?
+ ValidateInvalidAttributes (node.Attributes, node);
+ Hashtable sources = d ["sources"] as Hashtable;
+ if (sources == null) {
+ sources = new Hashtable ();
+ d ["sources"] = sources;
+ }
+ // FIXME: here I replace the table with fake static variable.
+ sources = static_sources;
+
+ foreach (XmlNode child in node.ChildNodes) {
+ XmlNodeType t = child.NodeType;
+ if (t == XmlNodeType.Whitespace || t == XmlNodeType.Comment)
+ continue;
+ if (t == XmlNodeType.Element) {
+ if (child.Name == "source")
+ AddTraceSource (sources, child);
+ else
+ ThrowUnrecognizedElement (child);
+// ValidateInvalidAttributes (child.Attributes, child);
+ }
+ else
+ ThrowUnrecognizedNode (child);
+ }
+ }
+
+ private void AddTraceSource (Hashtable sources, XmlNode node)
+ {
+ string name = null;
+ SourceLevels levels = SourceLevels.Error;
+ StringDictionary atts = new StringDictionary ();
+ foreach (XmlAttribute a in node.Attributes) {
+ switch (a.Name) {
+ case "name":
+ name = a.Value;
+ break;
+ case "switchValue":
+ levels = (SourceLevels) Enum.Parse (typeof (SourceLevels), a.Value);
+ break;
+ default:
+ atts [a.Name] = a.Value;
+ break;
+ }
+ }
+ if (name == null)
+ throw new ConfigurationException ("Mandatory attribute 'name' is missing in 'source' element.");
+
+ // FIXME: it should raise an error for duplicate name sources.
+ if (sources.ContainsKey (name))
+ return;
+
+ TraceSource source = new TraceSource (name, levels);
+ sources.Add (source.Name, source);
+
+ foreach (XmlNode child in node.ChildNodes) {
+ XmlNodeType t = child.NodeType;
+ if (t == XmlNodeType.Whitespace || t == XmlNodeType.Comment)
+ continue;
+ if (t == XmlNodeType.Element) {
+ if (child.Name == "listeners")
+ AddTraceListeners (child);
+ else
+ ThrowUnrecognizedElement (child);
+ ValidateInvalidAttributes (child.Attributes, child);
+ }
+ else
+ ThrowUnrecognizedNode (child);
+ }
+ }
+#endif
+
// only defines "add" and "remove", but "clear" also works
// for add, "name" and "type" are required; initializeData is optional
private void AddTraceListeners (XmlNode listenersNode)