2009-04-12 Gonzalo Paniagua Javier <gonzalo@novell.com>
[mono.git] / mcs / class / corlib / System.Threading / Monitor.cs
index d81b409c599ee3deaab5567243f894c25be3cd18..646efeeb9ae6f9e75093aeb7bdb466797ce7894d 100644 (file)
@@ -35,13 +35,20 @@ using System.Runtime.Remoting.Contexts;
 
 #if NET_2_0
 using System.Runtime.ConstrainedExecution;
+using System.Runtime.InteropServices;
 #endif
 
 namespace System.Threading
 {
+#if NET_2_0
+       [ComVisible (true)]
+       public static class Monitor
+       {
+#else
        public sealed class Monitor
        {
                private Monitor () {}
+#endif
 
                // Grabs the mutex on object 'obj', with a maximum
                // wait time 'ms' but doesn't block - if it can't get
@@ -49,37 +56,18 @@ namespace System.Threading
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private extern static bool Monitor_try_enter(object obj, int ms);
 
-#if NET_2_0
-               [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.MayFail)]
-#endif
-               public static void Enter(object obj) {
-                       if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
-                       }
-                       //if(obj.GetType().IsValueType==true) {
-                       //      throw new ArgumentException("Value type");
-                       //}
-
-                       Monitor_try_enter(obj, Timeout.Infinite);
-               }
+               // Enter/Exit are implemented directly as icalls for performance reasons
 
-               // Releases the mutex on object 'obj'
+               // Acquires the mutex on object 'obj'
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern static void Monitor_exit(object obj);
+               public extern static void Enter(object obj);
 
+               // Releases the mutex on object 'obj'
 #if NET_2_0
                [ReliabilityContractAttribute (Consistency.WillNotCorruptState, Cer.Success)]
 #endif
-               public static void Exit(object obj) {
-                       if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
-                       }
-                       //if(obj.GetType().IsValueType==true) {
-                       //      throw new ArgumentException("Value type");
-                       //}
-
-                       Monitor_exit(obj);
-               }
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               public extern static void Exit(object obj);
 
                // Signals one of potentially many objects waiting on
                // object 'obj'
@@ -92,7 +80,7 @@ namespace System.Threading
 
                public static void Pulse(object obj) {
                        if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
+                               throw new ArgumentNullException("obj");
                        }
                        if(Monitor_test_synchronised(obj)==false) {
                                throw new SynchronizationLockException("Object is not synchronized");
@@ -108,7 +96,7 @@ namespace System.Threading
 
                public static void PulseAll(object obj) {
                        if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
+                               throw new ArgumentNullException("obj");
                        }
                        if(Monitor_test_synchronised(obj)==false) {
                                throw new SynchronizationLockException("Object is not synchronized");
@@ -119,7 +107,7 @@ namespace System.Threading
 
                public static bool TryEnter(object obj) {
                        if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
+                               throw new ArgumentNullException("obj");
                        }
                        //if(obj.GetType().IsValueType==true) {
                        //      throw new ArgumentException("Value type");
@@ -130,7 +118,7 @@ namespace System.Threading
 
                public static bool TryEnter(object obj, int millisecondsTimeout) {
                        if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
+                               throw new ArgumentNullException("obj");
                        }
                        //if(obj.GetType().IsValueType==true) {
                        //      throw new ArgumentException("Value type");
@@ -144,7 +132,7 @@ namespace System.Threading
                        }
                        
                        if(millisecondsTimeout<0) {
-                               throw new ArgumentException("millisecondsTimeout negative");
+                               throw new ArgumentException("millisecondsTimeout", "negative value for millisecondsTimeout");
                        }
                        
                        return(Monitor_try_enter(obj, millisecondsTimeout));
@@ -152,7 +140,7 @@ namespace System.Threading
 
                public static bool TryEnter(object obj, TimeSpan timeout) {
                        if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
+                               throw new ArgumentNullException("obj");
                        }
                        //if(obj.GetType().IsValueType==true) {
                        //      throw new ArgumentException("Value type");
@@ -168,7 +156,7 @@ namespace System.Threading
                        }
 
                        if(ms < 0 || ms > Int32.MaxValue) {
-                               throw new ArgumentOutOfRangeException("timeout out of range");
+                               throw new ArgumentOutOfRangeException("timeout", "timeout out of range");
                        }
                        
                        return(Monitor_try_enter(obj, ms));
@@ -182,7 +170,7 @@ namespace System.Threading
 
                public static bool Wait(object obj) {
                        if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
+                               throw new ArgumentNullException("obj");
                        }
                        if(Monitor_test_synchronised(obj)==false) {
                                throw new SynchronizationLockException("Object is not synchronized");
@@ -193,25 +181,26 @@ namespace System.Threading
 
                public static bool Wait(object obj, int millisecondsTimeout) {
                        if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
+                               throw new ArgumentNullException("obj");
                        }
                        if(Monitor_test_synchronised(obj)==false) {
                                throw new SynchronizationLockException("Object is not synchronized");
                        }
-                       // LAMESPEC: no mention of timeout sanity checking
+                       if (millisecondsTimeout < 0 && millisecondsTimeout != Timeout.Infinite)
+                               throw new ArgumentOutOfRangeException ("millisecondsTimeout", "timeout out of range");
 
                        return(Monitor_wait(obj, millisecondsTimeout));
                }
 
                public static bool Wait(object obj, TimeSpan timeout) {
                        if(obj==null) {
-                               throw new ArgumentNullException("Object is null");
+                               throw new ArgumentNullException("obj");
                        }
                        // LAMESPEC: says to throw ArgumentException too
                        int ms=Convert.ToInt32(timeout.TotalMilliseconds);
                        
-                       if(ms < 0 || ms > Int32.MaxValue) {
-                               throw new ArgumentOutOfRangeException("timeout out of range");
+                       if((ms < 0 && ms != Timeout.Infinite) || ms > Int32.MaxValue) {
+                               throw new ArgumentOutOfRangeException("timeout", "timeout out of range");
                        }
                        if(Monitor_test_synchronised(obj)==false) {
                                throw new SynchronizationLockException("Object is not synchronized");