[corlib] Fixes security tests failures
[mono.git] / mcs / class / corlib / System.Threading / WaitHandle.cs
index 0380b5e21bd247133126dd19b235047810713356..5558efad52f46159fe85716d319e60902ec26eaa 100644 (file)
@@ -40,7 +40,9 @@ using System.Runtime.ConstrainedExecution;
 namespace System.Threading
 {
        [ComVisible (true)]
-       public abstract class WaitHandle : MarshalByRefObject, IDisposable
+       [StructLayout (LayoutKind.Sequential)]
+       public abstract class WaitHandle
+               : MarshalByRefObject, IDisposable
        {
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                private static extern bool WaitAll_internal(WaitHandle[] handles, int ms, bool exitContext);
@@ -115,7 +117,13 @@ namespace System.Threading
                                throw new ArgumentOutOfRangeException ("millisecondsTimeout");
 
                        try {
-                               if (exitContext) SynchronizationAttribute.ExitContext ();
+                               if (exitContext) {
+#if MONOTOUCH
+                                       throw new NotSupportedException ("exitContext == true is not supported");
+#else
+                                       SynchronizationAttribute.ExitContext ();
+#endif
+                               }
                                return(WaitAll_internal(waitHandles, millisecondsTimeout, false));
                        }
                        finally {
@@ -134,7 +142,13 @@ namespace System.Threading
                                throw new ArgumentOutOfRangeException ("timeout");
 
                        try {
-                               if (exitContext) SynchronizationAttribute.ExitContext ();
+                               if (exitContext) {
+#if MONOTOUCH
+                                       throw new NotSupportedException ("exitContext == true is not supported");
+#else
+                                       SynchronizationAttribute.ExitContext ();
+#endif
+                               }
                                return (WaitAll_internal (waitHandles, (int) ms, exitContext));
                        }
                        finally {
@@ -164,7 +178,13 @@ namespace System.Threading
                                throw new ArgumentOutOfRangeException ("millisecondsTimeout");
 
                        try {
-                               if (exitContext) SynchronizationAttribute.ExitContext ();
+                               if (exitContext) {
+#if MONOTOUCH
+                                       throw new NotSupportedException ("exitContext == true is not supported");
+#else
+                                       SynchronizationAttribute.ExitContext ();
+#endif
+                               }
                                return(WaitAny_internal(waitHandles, millisecondsTimeout, exitContext));
                        }
                        finally {
@@ -195,7 +215,13 @@ namespace System.Threading
                                throw new ArgumentOutOfRangeException ("timeout");
 
                        try {
-                               if (exitContext) SynchronizationAttribute.ExitContext ();
+                               if (exitContext) {
+#if MONOTOUCH
+                                       throw new NotSupportedException ("exitContext == true is not supported");
+#else
+                                       SynchronizationAttribute.ExitContext ();
+#endif
+                               }
                                return (WaitAny_internal(waitHandles, (int) ms, exitContext));
                        }
                        finally {
@@ -208,16 +234,12 @@ namespace System.Threading
                        // FIXME
                }
 
-               public virtual void Close() {
+               public virtual void Close ()
+               {
                        Dispose(true);
-                       GC.SuppressFinalize (this);
                }
 
-#if NET_4_0 || MOBILE
                public void Dispose ()
-#else          
-               void IDisposable.Dispose ()
-#endif
                {
                        Close ();
                }
@@ -251,7 +273,6 @@ namespace System.Threading
                protected virtual void Dispose (bool explicitDisposing)
                {
                        if (!disposed){
-                               disposed = true;
 
                                //
                                // This is only the case if the handle was never properly initialized
@@ -261,6 +282,10 @@ namespace System.Threading
                                        return;
 
                                lock (this){
+                                       if (disposed)
+                                               return;
+
+                                       disposed = true;
                                        if (safe_wait_handle != null)
                                                safe_wait_handle.Dispose ();
                                }
@@ -341,13 +366,18 @@ namespace System.Threading
 
                        bool release = false;
                        try {
-                               if (exitContext)
+                               if (exitContext) {
+#if !MONOTOUCH
                                        SynchronizationAttribute.ExitContext ();
+#endif
+                               }
                                safe_wait_handle.DangerousAddRef (ref release);
                                return (WaitOne_internal(safe_wait_handle.DangerousGetHandle (), millisecondsTimeout, exitContext));
                        } finally {
+#if !MONOTOUCH
                                if (exitContext)
                                        SynchronizationAttribute.EnterContext ();
+#endif
                                if (release)
                                        safe_wait_handle.DangerousRelease ();
                        }
@@ -372,14 +402,19 @@ namespace System.Threading
 
                        bool release = false;
                        try {
-                               if (exitContext)
+                               if (exitContext) {
+#if !MONOTOUCH
                                        SynchronizationAttribute.ExitContext ();
+#endif
+                               }
                                safe_wait_handle.DangerousAddRef (ref release);
                                return (WaitOne_internal(safe_wait_handle.DangerousGetHandle (), (int) ms, exitContext));
                        }
                        finally {
+#if !MONOTOUCH
                                if (exitContext)
                                        SynchronizationAttribute.EnterContext ();
+#endif
                                if (release)
                                        safe_wait_handle.DangerousRelease ();
                        }
@@ -403,9 +438,5 @@ namespace System.Threading
                
                protected static readonly IntPtr InvalidHandle = (IntPtr) (-1);
                bool disposed = false;
-
-               ~WaitHandle() {
-                       Dispose(false);
-               }
        }
 }