Excluded test DefaultType in ToolboxItemAttributeTests.cs under 'TARGET_JVM'
[mono.git] / mcs / class / System / System.Diagnostics / DiagnosticsConfigurationHandler.cs
index 2452a1c4e9f60ee1b85cc5a12ba3064c2139b77b..8dd3ff9225e2e2b698e88d17e196402228d04b8f 100644 (file)
@@ -33,7 +33,9 @@
 //
 using System;
 using System.Collections;
+using System.Collections.Specialized;
 using System.Configuration;
+using System.Threading;
 #if (XML_DEP)
 using System.Xml;
 #endif
@@ -41,12 +43,31 @@ namespace System.Diagnostics
 {
        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;
                        }
                }
        }
@@ -62,6 +83,9 @@ namespace System.Diagnostics
                        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)
@@ -150,7 +174,8 @@ namespace System.Diagnostics
                                                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);
@@ -172,6 +197,17 @@ namespace System.Diagnostics
                        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);
@@ -216,6 +252,9 @@ namespace System.Diagnostics
                                        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);
@@ -223,6 +262,82 @@ namespace System.Diagnostics
                        }
                }
 
+#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)