[Mono-dev] UriParser.cs - Threading fixes

Alan McGovern alan.mcgovern at gmail.com
Fri Oct 31 11:38:06 EDT 2008


There are a few thread-unsafe accesses to the hashtable which I've fixed.
I've also cleaned up how the initial table is populated by removing
redundent calls to CreateDefaults ().

 Is this ok to commit?


Index: UriParser.cs
===================================================================
--- UriParser.cs    (revision 117256)
+++ UriParser.cs    (working copy)
@@ -38,7 +38,7 @@
     public abstract class UriParser {

         static object lock_object = new object ();
-        static Hashtable table;
+        static Hashtable table = CreateDefaults ();

         private string scheme_name;
         private int default_port;
@@ -211,11 +211,8 @@

         // static methods

-        private static void CreateDefaults ()
+        private static Hashtable CreateDefaults ()
         {
-            if (table != null)
-                return;
-
             Hashtable newtable = new Hashtable ();
             InternalRegister (newtable, new DefaultUriParser (),
Uri.UriSchemeFile, -1);
             InternalRegister (newtable, new DefaultUriParser (),
Uri.UriSchemeFtp, 21);
@@ -229,13 +226,8 @@
             InternalRegister (newtable, new DefaultUriParser (),
Uri.UriSchemeNntp, 119);
             // not defined in Uri.UriScheme* but a parser class exists
             InternalRegister (newtable, new DefaultUriParser (), "ldap",
389);
-
-            lock (lock_object) {
-                if (table == null)
-                    table = newtable;
-                else
-                    newtable = null;
-            }
+
+            return newtable;
         }

         public static bool IsKnownScheme (string schemeName)
@@ -245,9 +237,10 @@
             if (schemeName.Length == 0)
                 throw new ArgumentOutOfRangeException ("schemeName");

-            CreateDefaults ();
             string lc = schemeName.ToLower (CultureInfo.InvariantCulture);
-            return (table [lc] != null);
+
+            lock (lock_object)
+                return (table [lc] != null);
         }

         // *no* check version
@@ -280,14 +273,16 @@
             if ((defaultPort < -1) || (defaultPort >= UInt16.MaxValue))
                 throw new ArgumentOutOfRangeException ("defaultPort");

-            CreateDefaults ();
-
             string lc = schemeName.ToLower (CultureInfo.InvariantCulture);
-            if (table [lc] != null) {
-                string msg = Locale.GetText ("Scheme '{0}' is already
registred.");
-                throw new InvalidOperationException (msg);
+
+            lock (lock_object) {
+                if (table [lc] != null) {
+                    string msg = Locale.GetText ("Scheme '{0}' is already
registred.");
+                    throw new InvalidOperationException (msg);
+                }
+
+                InternalRegister (table, uriParser, lc, defaultPort);
             }
-            InternalRegister (table, uriParser, lc, defaultPort);
         }

         internal static UriParser GetParser (string schemeName)
@@ -295,10 +290,10 @@
             if (schemeName == null)
                 return null;

-            CreateDefaults ();
-
             string lc = schemeName.ToLower (CultureInfo.InvariantCulture);
-            return (UriParser) table [lc];
+
+            lock (lock_object)
+                return (UriParser) table [lc];
         }
     }
 }
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://lists.ximian.com/pipermail/mono-devel-list/attachments/20081031/01044aae/attachment-0001.html 
-------------- next part --------------
A non-text attachment was scrubbed...
Name: uriparserfix.patch
Type: text/x-patch
Size: 2587 bytes
Desc: not available
Url : http://lists.ximian.com/pipermail/mono-devel-list/attachments/20081031/01044aae/attachment-0001.bin 


More information about the Mono-devel-list mailing list