Merge pull request #2653 from lambdageek/dev/exception_type-1
authormonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 22 Feb 2016 19:30:33 +0000 (19:30 +0000)
committermonojenkins <jo.shields+jenkins@xamarin.com>
Mon, 22 Feb 2016 19:30:33 +0000 (19:30 +0000)
[runtime] Don't access MonoClass::exception_type directly.

Use `mono_class_get_failure ()` and `mono_class_has_failed ()`

This is mostly just cleanup refactoring at this point that will make it easier to change how exception_type is used.

Also from this exercise we've learned that most of the class handling code just cares whether the class has an error or not, not what sort of error it was.

18 files changed:
external/referencesource
mcs/class/Microsoft.Build.Utilities/Microsoft.Build.Utilities/ProcessWrapper.cs
mcs/class/Mono.Debugger.Soft/Test/dtest.cs
mcs/class/corlib/System.Threading/EventWaitHandle.cs
mcs/class/corlib/System.Threading/NativeEventCalls.cs
mcs/class/corlib/System.Threading/RegisteredWaitHandle.cs
mcs/class/corlib/System.Threading/Timer.cs
mcs/class/corlib/System.Threading/WaitHandle.cs
mcs/class/corlib/System/Environment.cs
mcs/class/corlib/Test/System.Threading/AutoResetEventTest.cs
mcs/class/corlib/corlib.dll.sources
mono/io-layer/processes.c
mono/metadata/appdomain.c
mono/metadata/object-internals.h
mono/metadata/object.c
mono/metadata/threads-types.h
mono/metadata/threads.c
scripts/dmcs.in

index bf43bae316ec6216e79beb95b2ba25137d91908d..423e8998d55f168e2aa5da2c0e00ec6dd1356cbf 160000 (submodule)
@@ -1 +1 @@
-Subproject commit bf43bae316ec6216e79beb95b2ba25137d91908d
+Subproject commit 423e8998d55f168e2aa5da2c0e00ec6dd1356cbf
index d78c1eba66d1ac49a666544dfcf9612a953fb5ae..1674ff8b5dc3095f027cd6ffd60d1562e5e056d4 100644 (file)
@@ -13,6 +13,7 @@ namespace Microsoft.Build.Utilities
                ManualResetEvent endEventErr = new ManualResetEvent (false);
                ManualResetEvent endEventExit = new ManualResetEvent (false);
                bool done;
+               bool disposed;
                object lockObj = new object ();
 
                public ProcessWrapper ()
@@ -26,29 +27,41 @@ namespace Microsoft.Build.Utilities
                        base.EnableRaisingEvents = true;
 
                        base.Exited += (s, args) => {
-                               endEventExit.Set ();
+                               try {
+                                       endEventExit.Set ();
+                                       WaitHandle.WaitAll (new WaitHandle[] { endEventOut, endEventErr });
+                               } catch (ObjectDisposedException) {
+                                       return; // we already called Dispose
+                               }
 
-                               WaitHandle.WaitAll (new WaitHandle[] { endEventOut, endEventErr });
                                OnExited (this, EventArgs.Empty);
                        };
 
                        base.OutputDataReceived += (s, args) => {
                                if (args.Data == null) {
-                                       endEventOut.Set ();
+                                       try {
+                                               endEventOut.Set ();
+                                       } catch (ObjectDisposedException) {
+                                               return; // we already called Dispose
+                                       }
                                } else {
                                        ProcessEventHandler handler = OutputStreamChanged;
                                        if (handler != null)
-                                               handler (this, args.Data);
+                                               handler (this, args.Data + Environment.NewLine);
                                }
                        };
 
                        base.ErrorDataReceived += (s, args) => {
                                if (args.Data == null) {
-                                       endEventErr.Set ();
+                                       try {
+                                               endEventErr.Set ();
+                                       } catch (ObjectDisposedException) {
+                                               return; // we already called Dispose
+                                       }
                                } else {
                                        ProcessEventHandler handler = ErrorStreamChanged;
                                        if (handler != null)
-                                               handler (this, args.Data);
+                                               handler (this, args.Data + Environment.NewLine);
                                }
                        };
 
@@ -71,24 +84,28 @@ namespace Microsoft.Build.Utilities
 
                protected override void Dispose (bool disposing)
                {
-                       lock (lockObj) {
-                               if (endEventOut == null)
-                                       return;
-                       }
+                       if (disposed)
+                               return;
 
                        if (!done)
                                ((IAsyncOperation)this).Cancel ();
 
+                       // if we race with base.Exited, we don't want to hang on WaitAll (endEventOut, endEventErr)
+                       endEventOut.Set ();
+                       endEventErr.Set ();
+
                        endEventOut.Close ();
                        endEventErr.Close ();
                        endEventExit.Close ();
 
+                       disposed = true;
+
                        base.Dispose (disposing);
                }
 
                void CheckDisposed ()
                {
-                       if (endEventOut == null)
+                       if (disposed)
                                throw new ObjectDisposedException ("ProcessWrapper");
                }
 
index c54baffecf94c174e38e13a24b9b26f32ded1c05..086c6f5f9aa92214c1c9e00bf2ee9d8b98968484 100644 (file)
@@ -3620,12 +3620,15 @@ public class DebuggerTests
                Assert.AreEqual (ThreadState.WaitSleepJoin, thread.ThreadState, "#6");
 
                frames = thread.GetFrames ();
-               Assert.AreEqual (4, frames.Length, "#7");
-               Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8");
-               Assert.AreEqual ("WaitOne", frames [1].Method.Name, "#8.1");
-               Assert.AreEqual ("wait_one", frames [2].Method.Name, "#9");
-               Assert.AreEqual ("Main", frames [3].Method.Name, "#10");
-
+               Assert.AreEqual (8, frames.Length, "#7");
+               Assert.AreEqual ("WaitOne_internal", frames [0].Method.Name, "#8.0");
+               Assert.AreEqual ("WaitOneNative", frames [1].Method.Name, "#8.1");
+               Assert.AreEqual ("InternalWaitOne", frames [2].Method.Name, "#8.2");
+               Assert.AreEqual ("WaitOne", frames [3].Method.Name, "#8.3");
+               Assert.AreEqual ("WaitOne", frames [4].Method.Name, "#8.4");
+               Assert.AreEqual ("WaitOne", frames [5].Method.Name, "#8.5");
+               Assert.AreEqual ("wait_one", frames [6].Method.Name, "#8.6");
+               Assert.AreEqual ("Main", frames [7].Method.Name, "#8.7");
 
                var frame = frames [0];
                Assert.IsTrue (frame.IsNativeTransition, "#11.1");
@@ -3634,12 +3637,12 @@ public class DebuggerTests
                        Assert.Fail ("Known limitation - can't get info from m2n frames");
                } catch (AbsentInformationException) {}
 
-               frame = frames [1];
+               frame = frames [3];
                Assert.IsFalse (frame.IsNativeTransition, "#12.1");
                var wait_one_this = frame.GetThis ();
                Assert.IsNotNull (wait_one_this, "#12.2");
 
-               frame = frames [2];
+               frame = frames [6];
                var locals = frame.GetVisibleVariables ();
                Assert.AreEqual (1, locals.Count, "#13.1");
 
index 7d1668ca8381ba4009a12f9a5d06f987cad8776f..fba21dc3ce56b3a51a69c083fef85fc8fa16763c 100644 (file)
@@ -195,7 +195,7 @@ namespace System.Threading
                        lock (this) {
                                CheckDisposed ();
                        
-                               return (NativeEventCalls.ResetEvent_internal (Handle));
+                               return NativeEventCalls.ResetEvent (SafeWaitHandle);
                        }
                }
                
@@ -204,9 +204,23 @@ namespace System.Threading
                        lock (this) {
                                CheckDisposed ();
                        
-                               return (NativeEventCalls.SetEvent_internal (Handle));
+                               return NativeEventCalls.SetEvent (SafeWaitHandle);
                        }
                }
+
+               internal void CheckDisposed ()
+               {
+                       if (disposed)
+                               throw new ObjectDisposedException (GetType ().FullName);
+               }
+
+               bool disposed;
+               protected override void Dispose(bool explicitDisposing)
+               {
+                       base.Dispose (explicitDisposing);
+                       disposed = true;
+               }
+
 #if !NET_2_1
                public void SetAccessControl (EventWaitHandleSecurity eventSecurity)
                {
index 3a0c12361268f373c363f583bdfdb9b8eb6ebf96..b0320579bfa227ec3a8058fe50ab22774d6fbf6d 100644 (file)
@@ -33,6 +33,7 @@
 
 using System;
 using System.Runtime.CompilerServices;
+using Microsoft.Win32.SafeHandles;
 
 #if !MOBILE
 using System.Security.AccessControl;
@@ -46,11 +47,35 @@ namespace System.Threading
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public static extern IntPtr CreateEvent_internal(bool manual,bool initial,string name, out bool created);
 
+               public static bool SetEvent (SafeWaitHandle handle)
+               {
+                       bool release = false;
+                       try {
+                               handle.DangerousAddRef (ref release);
+                               return SetEvent_internal (handle.DangerousGetHandle ());
+                       } finally {
+                               if (release)
+                                       handle.DangerousRelease ();
+                       }
+               }
+
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public static extern bool SetEvent_internal(IntPtr handle);
+               static extern bool SetEvent_internal(IntPtr handle);
+
+               public static bool ResetEvent (SafeWaitHandle handle)
+               {
+                       bool release = false;
+                       try {
+                               handle.DangerousAddRef (ref release);
+                               return ResetEvent_internal (handle.DangerousGetHandle ());
+                       } finally {
+                               if (release)
+                                       handle.DangerousRelease ();
+                       }
+               }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               public static extern bool ResetEvent_internal(IntPtr handle);
+               static extern bool ResetEvent_internal(IntPtr handle);
        
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
                public static extern void CloseEvent_internal (IntPtr handle);
index 1c8f4768d318aeb2ebb6f2eee416da7676e5fa15..960ecf6e7b857595371308d71456e4c2fe0dad93 100644 (file)
@@ -84,7 +84,7 @@ namespace System.Threading
                                lock (this) {
                                        _unregistered = true;
                                        if (_callsInProcess == 0 && _finalEvent != null)
-                                               NativeEventCalls.SetEvent_internal (_finalEvent.Handle);
+                                               NativeEventCalls.SetEvent (_finalEvent.SafeWaitHandle);
                                }
                        } catch (ObjectDisposedException) {
                                // Can happen if we called Unregister before we had time to execute Wait
@@ -108,7 +108,7 @@ namespace System.Threading
                        {
                                _callsInProcess--;
                                if (_unregistered && _callsInProcess == 0 && _finalEvent != null)
-                                       NativeEventCalls.SetEvent_internal (_finalEvent.Handle);
+                                       NativeEventCalls.SetEvent (_finalEvent.SafeWaitHandle);
                        }
                }
 
index 9efb484e3d85b6ec614f57c271d15f35eb8e96ff..d1546a8bfcaa80632664c766dd64e69f70977b22 100644 (file)
@@ -166,7 +166,7 @@ namespace System.Threading
                        if (notifyObject == null)
                                throw new ArgumentNullException ("notifyObject");
                        Dispose ();
-                       NativeEventCalls.SetEvent_internal (notifyObject.Handle);
+                       NativeEventCalls.SetEvent (notifyObject.SafeWaitHandle);
                        return true;
                }
 
index 5558efad52f46159fe85716d319e60902ec26eaa..019647bc0bd85170bb18b74ae176517b3f1b1ad9 100644 (file)
@@ -39,404 +39,100 @@ using System.Runtime.ConstrainedExecution;
 
 namespace System.Threading
 {
-       [ComVisible (true)]
        [StructLayout (LayoutKind.Sequential)]
-       public abstract class WaitHandle
+       public abstract partial class WaitHandle
                : MarshalByRefObject, IDisposable
        {
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private static extern bool WaitAll_internal(WaitHandle[] handles, int ms, bool exitContext);
-               
-               static void CheckArray (WaitHandle [] handles, bool waitAll)
-               {
-                       if (handles == null)
-                               throw new ArgumentNullException ("waitHandles");
-
-                       int length = handles.Length;
-                       if (length > 64)
-                               throw new NotSupportedException ("Too many handles");
-
-                       if (handles.Length == 0) {
-                               // MS throws different exceptions from the different methods.
-                               if (waitAll)
-                                       throw new ArgumentNullException ("waitHandles");
-                               else
-                                       throw new ArgumentException ();
-                       }
-
-#if false
-                       //
-                       // Although we should thrown an exception if this is an STA thread,
-                       // Mono does not know anything about STA threads, and just makes
-                       // things like Paint.NET not even possible to work.
-                       //
-                       // See bug #78455 for the bug this is supposed to fix. 
-                       // 
-                       if (waitAll && length > 1 && IsSTAThread)
-                               throw new NotSupportedException ("WaitAll for multiple handles is not allowed on an STA thread.");
-#endif
-                       foreach (WaitHandle w in handles) {
-                               if (w == null)
-                                       throw new ArgumentNullException ("waitHandles", "null handle");
-
-                               if (w.safe_wait_handle == null)
-                                       throw new ArgumentException ("null element found", "waitHandle");
-
-                       }
-               }
-#if false
-               // usage of property is commented - see above
-               static bool IsSTAThread {
-                       get {
-                               bool isSTA = Thread.CurrentThread.ApartmentState ==
-                                       ApartmentState.STA;
-
-                               // FIXME: remove this check after Thread.ApartmentState
-                               // has been properly implemented.
-                               if (!isSTA) {
-                                       Assembly asm = Assembly.GetEntryAssembly ();
-                                       if (asm != null)
-                                               isSTA = asm.EntryPoint.GetCustomAttributes (typeof (STAThreadAttribute), false).Length > 0;
-                               }
-
-                               return isSTA;
-                       }
-               }
-#endif
-               public static bool WaitAll(WaitHandle[] waitHandles)
-               {
-                       CheckArray (waitHandles, true);
-                       return(WaitAll_internal(waitHandles, Timeout.Infinite, false));
-               }
-
-               public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext)
-               {
-                       CheckArray (waitHandles, true);
-                       // check negative - except for -1 (which is Timeout.Infinite)
-                       if (millisecondsTimeout < Timeout.Infinite)
-                               throw new ArgumentOutOfRangeException ("millisecondsTimeout");
-
-                       try {
-                               if (exitContext) {
-#if MONOTOUCH
-                                       throw new NotSupportedException ("exitContext == true is not supported");
-#else
-                                       SynchronizationAttribute.ExitContext ();
-#endif
-                               }
-                               return(WaitAll_internal(waitHandles, millisecondsTimeout, false));
-                       }
-                       finally {
-                               if (exitContext) SynchronizationAttribute.EnterContext ();
-                       }
-               }
+               protected static readonly IntPtr InvalidHandle = (IntPtr) (-1);
 
-               public static bool WaitAll(WaitHandle[] waitHandles,
-                                          TimeSpan timeout,
-                                          bool exitContext)
+               static int WaitMultiple(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext, bool WaitAll)
                {
-                       CheckArray (waitHandles, true);
-                       long ms = (long) timeout.TotalMilliseconds;
-                       
-                       if (ms < -1 || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout");
-
-                       try {
-                               if (exitContext) {
 #if MONOTOUCH
-                                       throw new NotSupportedException ("exitContext == true is not supported");
-#else
-                                       SynchronizationAttribute.ExitContext ();
+                       if (exitContext)
+                               throw new NotSupportedException ("exitContext == true is not supported");
 #endif
-                               }
-                               return (WaitAll_internal (waitHandles, (int) ms, exitContext));
-                       }
-                       finally {
-                               if (exitContext) SynchronizationAttribute.EnterContext ();
-                       }
-               }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private static extern int WaitAny_internal(WaitHandle[] handles, int ms, bool exitContext);
-
-               // LAMESPEC: Doesn't specify how to signal failures
-               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-               public static int WaitAny(WaitHandle[] waitHandles)
-               {
-                       CheckArray (waitHandles, false);
-                       return(WaitAny_internal(waitHandles, Timeout.Infinite, false));
-               }
-
-               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-               public static int WaitAny(WaitHandle[] waitHandles,
-                                         int millisecondsTimeout,
-                                         bool exitContext)
-               {
-                       CheckArray (waitHandles, false);
-                       // check negative - except for -1 (which is Timeout.Infinite)
-                       if (millisecondsTimeout < Timeout.Infinite)
-                               throw new ArgumentOutOfRangeException ("millisecondsTimeout");
+                       int release_last = -1;
 
                        try {
-                               if (exitContext) {
-#if MONOTOUCH
-                                       throw new NotSupportedException ("exitContext == true is not supported");
-#else
+                               if (exitContext)
                                        SynchronizationAttribute.ExitContext ();
-#endif
-                               }
-                               return(WaitAny_internal(waitHandles, millisecondsTimeout, exitContext));
-                       }
-                       finally {
-                               if (exitContext) SynchronizationAttribute.EnterContext ();
-                       }
-               }
-
-               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-               public static int WaitAny(WaitHandle[] waitHandles, TimeSpan timeout)
-               {
-                       return WaitAny (waitHandles, timeout, false);
-               }
-
-               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-               public static int WaitAny(WaitHandle[] waitHandles, int millisecondsTimeout)
-               {
-                       return WaitAny (waitHandles, millisecondsTimeout, false);
-               }
 
-               [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-               public static int WaitAny(WaitHandle[] waitHandles,
-                                         TimeSpan timeout, bool exitContext)
-               {
-                       CheckArray (waitHandles, false);
-                       long ms = (long) timeout.TotalMilliseconds;
-                       
-                       if (ms < -1 || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout");
-
-                       try {
-                               if (exitContext) {
-#if MONOTOUCH
-                                       throw new NotSupportedException ("exitContext == true is not supported");
-#else
-                                       SynchronizationAttribute.ExitContext ();
-#endif
+                               for (int i = 0; i < waitHandles.Length; ++i) {
+                                       try {
+                                       } finally {
+                                               /* we have to put it in a finally block, to avoid having a ThreadAbortException
+                                                * between the return from DangerousAddRef and the assignement to release_last */
+                                               bool release = false;
+                                               waitHandles [i].SafeWaitHandle.DangerousAddRef (ref release);
+                                               release_last = i;
+                                       }
                                }
-                               return (WaitAny_internal(waitHandles, (int) ms, exitContext));
-                       }
-                       finally {
-                               if (exitContext) SynchronizationAttribute.EnterContext ();
-                       }
-               }
-
-               protected WaitHandle()
-               {
-                       // FIXME
-               }
-
-               public virtual void Close ()
-               {
-                       Dispose(true);
-               }
-
-               public void Dispose ()
-               {
-                       Close ();
-               }
-
-               public const int WaitTimeout = 258;
 
-               //
-               // In 2.0 we use SafeWaitHandles instead of IntPtrs
-               //
-               SafeWaitHandle safe_wait_handle;
-
-               [Obsolete ("In the profiles > 2.x, use SafeHandle instead of Handle")]
-               public virtual IntPtr Handle {
-                       get {
-                               return safe_wait_handle.DangerousGetHandle ();
-                       }
-
-                       [SecurityPermission (SecurityAction.LinkDemand, UnmanagedCode = true)]
-                       [SecurityPermission (SecurityAction.InheritanceDemand, UnmanagedCode = true)]
-                       set {
-                               if (value == InvalidHandle)
-                                       safe_wait_handle = new SafeWaitHandle (InvalidHandle, false);
+                               if (WaitAll)
+                                       return WaitAll_internal (waitHandles, millisecondsTimeout, exitContext);
                                else
-                                       safe_wait_handle = new SafeWaitHandle (value, true);
-                       }
-               }
-               
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private extern bool WaitOne_internal(IntPtr handle, int ms, bool exitContext);
-
-               protected virtual void Dispose (bool explicitDisposing)
-               {
-                       if (!disposed){
-
-                               //
-                               // This is only the case if the handle was never properly initialized
-                               // most likely a bug in the derived class
-                               //
-                               if (safe_wait_handle == null)
-                                       return;
-
-                               lock (this){
-                                       if (disposed)
-                                               return;
-
-                                       disposed = true;
-                                       if (safe_wait_handle != null)
-                                               safe_wait_handle.Dispose ();
+                                       return WaitAny_internal (waitHandles, millisecondsTimeout, exitContext);
+                       } finally {
+                               for (int i = release_last; i >= 0; --i) {
+                                       waitHandles [i].SafeWaitHandle.DangerousRelease ();
                                }
-                       }
-               }
-
-               public SafeWaitHandle SafeWaitHandle {
-                       [ReliabilityContract (Consistency.WillNotCorruptState, Cer.MayFail)]
-                       get {
-                               return safe_wait_handle;
-                       }
 
-                       [ReliabilityContract (Consistency.WillNotCorruptState, Cer.Success)]
-                       set {
-                               if (value == null)
-                                       safe_wait_handle = new SafeWaitHandle (InvalidHandle, false);
-                               else
-                                       safe_wait_handle = value;
+                               if (exitContext)
+                                       SynchronizationAttribute.EnterContext ();
                        }
                }
 
-               public static bool SignalAndWait (WaitHandle toSignal,
-                                                 WaitHandle toWaitOn)
-               {
-                       return SignalAndWait (toSignal, toWaitOn, -1, false);
-               }
-               
-               public static bool SignalAndWait (WaitHandle toSignal,
-                                                 WaitHandle toWaitOn,
-                                                 int millisecondsTimeout,
-                                                 bool exitContext)
-               {
-                       if (toSignal == null)
-                               throw new ArgumentNullException ("toSignal");
-                       if (toWaitOn == null)
-                               throw new ArgumentNullException ("toWaitOn");
-
-                       if (millisecondsTimeout < -1)
-                               throw new ArgumentOutOfRangeException ("millisecondsTimeout");
-
-                       return SignalAndWait_Internal (toSignal.Handle, toWaitOn.Handle, millisecondsTimeout, exitContext);
-               }
-               
-               public static bool SignalAndWait (WaitHandle toSignal,
-                                                 WaitHandle toWaitOn,
-                                                 TimeSpan timeout,
-                                                 bool exitContext)
-               {
-                       double ms = timeout.TotalMilliseconds;
-                       if (ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout");
-
-                       return SignalAndWait (toSignal, toWaitOn, Convert.ToInt32 (ms), false);
-               }
-
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern bool SignalAndWait_Internal (IntPtr toSignal, IntPtr toWaitOn, int ms, bool exitContext);
+               private static extern int WaitAll_internal(WaitHandle[] handles, int ms, bool exitContext);
 
-               public virtual bool WaitOne()
-               {
-                       CheckDisposed ();
-                       bool release = false;
-                       try {
-                               safe_wait_handle.DangerousAddRef (ref release);
-                               return (WaitOne_internal(safe_wait_handle.DangerousGetHandle (), Timeout.Infinite, false));
-                       } finally {
-                               if (release)
-                                       safe_wait_handle.DangerousRelease ();
-                       }
-               }
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               private static extern int WaitAny_internal(WaitHandle[] handles, int ms, bool exitContext);
 
-               public virtual bool WaitOne(int millisecondsTimeout, bool exitContext)
+               static int WaitOneNative (SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext)
                {
-                       CheckDisposed ();
-                       // check negative - except for -1 (which is Timeout.Infinite)
-                       if (millisecondsTimeout < Timeout.Infinite)
-                               throw new ArgumentOutOfRangeException ("millisecondsTimeout");
+#if MONOTOUCH
+                       if (exitContext)
+                               throw new NotSupportedException ("exitContext == true is not supported");
+#endif
 
                        bool release = false;
                        try {
-                               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 ();
-                       }
-               }
+                                       SynchronizationAttribute.ExitContext ();
 
-               public virtual bool WaitOne (int millisecondsTimeout)
-               {
-                       return WaitOne (millisecondsTimeout, false);
-               }
+                               waitableSafeHandle.DangerousAddRef (ref release);
 
-               public virtual bool WaitOne (TimeSpan timeout)
-               {
-                       return WaitOne (timeout, false);
-               }
-
-               public virtual bool WaitOne(TimeSpan timeout, bool exitContext)
-               {
-                       CheckDisposed ();
-                       long ms = (long) timeout.TotalMilliseconds;
-                       if (ms < -1 || ms > Int32.MaxValue)
-                               throw new ArgumentOutOfRangeException ("timeout");
+                               return WaitOne_internal (waitableSafeHandle.DangerousGetHandle (), (int) millisecondsTimeout, exitContext);
+                       } finally {
+                               if (release)
+                                       waitableSafeHandle.DangerousRelease ();
 
-                       bool release = false;
-                       try {
-                               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 ();
                        }
                }
 
-               internal void CheckDisposed ()
-               {
-                       if (disposed || safe_wait_handle == null)
-                               throw new ObjectDisposedException (GetType ().FullName);
-               }
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               static extern int WaitOne_internal(IntPtr handle, int ms, bool exitContext);
 
-               public static bool WaitAll(WaitHandle[] waitHandles, int millisecondsTimeout)
+               static int SignalAndWaitOne (SafeWaitHandle waitHandleToSignal,SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout, bool hasThreadAffinity,  bool exitContext)
                {
-                       return WaitAll (waitHandles, millisecondsTimeout, false);
-               }
+                       bool releaseHandleToSignal = false, releaseHandleToWaitOn = false;
+                       try {
+                               waitHandleToSignal.DangerousAddRef (ref releaseHandleToSignal);
+                               waitHandleToWaitOn.DangerousAddRef (ref releaseHandleToWaitOn);
 
-               public static bool WaitAll(WaitHandle[] waitHandles, TimeSpan timeout)
-               {
-                       return WaitAll (waitHandles, timeout, false);
+                               return SignalAndWait_Internal (waitHandleToSignal.DangerousGetHandle (), waitHandleToWaitOn.DangerousGetHandle (), millisecondsTimeout, exitContext);
+                       } finally {
+                               if (releaseHandleToSignal)
+                                       waitHandleToSignal.DangerousRelease ();
+                               if (releaseHandleToWaitOn)
+                                       waitHandleToWaitOn.DangerousRelease ();
+                       }
                }
-               
-               protected static readonly IntPtr InvalidHandle = (IntPtr) (-1);
-               bool disposed = false;
+
+               [MethodImplAttribute(MethodImplOptions.InternalCall)]
+               static extern int SignalAndWait_Internal (IntPtr toSignal, IntPtr toWaitOn, int ms, bool exitContext);
        }
 }
index 126777e1923e663dd4ad2467e788782ac2956b07..70a4dea80df5d68f1a7de17fc2dfde0121e99606 100644 (file)
@@ -57,7 +57,7 @@ namespace System {
                 * of icalls, do not require an increment.
                 */
 #pragma warning disable 169
-               private const int mono_corlib_version = 142;
+               private const int mono_corlib_version = 143;
 #pragma warning restore 169
 
                [ComVisible (true)]
index 8a3ad3b76ab27956cfbdb42e9252afaa5a63cf19..cf35cfbc6a31cd5ed9c2a87c9b27821021320edf 100644 (file)
@@ -90,7 +90,7 @@ namespace MonoTests.System.Threading
                        SafeWaitHandle swh1 = are1.SafeWaitHandle;
                        are1.Handle = (IntPtr) (-1);
                        Assert.IsTrue (swh1 != are1.SafeWaitHandle, "#1");
-                       Assert.IsFalse (swh1.IsClosed, "#2");
+                       Assert.IsTrue (swh1.IsClosed, "#2"); // After testing on Windows/.NET, IsClosed returns true
                        Assert.IsFalse (swh1.IsInvalid, "#3");
                        Assert.IsFalse (are1.SafeWaitHandle.IsClosed, "#4");
                        Assert.IsTrue (are1.SafeWaitHandle.IsInvalid, "#5");
index 036771deee1793223602d7b69014693090bc617b..00cccc2c0234a20685989fae9df9400f49680be9 100644 (file)
@@ -1571,6 +1571,7 @@ ReferenceSources/SecurityContext.cs
 ../../../external/referencesource/mscorlib/system/threading/timeout.cs
 ../../../external/referencesource/mscorlib/system/threading/waithandlecannotbeopenedexception.cs
 ../../../external/referencesource/mscorlib/system/threading/threadpool.cs
+../../../external/referencesource/mscorlib/system/threading/waithandle.cs
 
 ../../../external/referencesource/mscorlib/system/threading/Tasks/AsyncCausalityTracer.cs
 ../../../external/referencesource/mscorlib/system/threading/Tasks/BeginEndAwaitableAdapter.cs
index 385945f4301cbf99ef96da735e74c01b1d022c54..d54f84bd3242abb26c69473631f355fb4d1f5512 100644 (file)
@@ -2757,6 +2757,11 @@ process_wait (gpointer handle, guint32 timeout, gboolean alertable)
        if (!mp) {
                pid_t res;
 
+               if (pid == mono_process_current_pid ()) {
+                       MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s (%p, %u): waiting on current process", __func__, handle, timeout);
+                       return WAIT_TIMEOUT;
+               }
+
                /* This path is used when calling Process.HasExited, so
                 * it is only used to poll the state of the process, not
                 * to actually wait on it to exit */
index 7bc9ab9c88163dee7e74afa2a3a0fa54b8a4f3a1..226e0071784a78ae6c680f8688306f2dfbe67d4c 100644 (file)
@@ -80,7 +80,7 @@
  * Changes which are already detected at runtime, like the addition
  * of icalls, do not require an increment.
  */
-#define MONO_CORLIB_VERSION 142
+#define MONO_CORLIB_VERSION 143
 
 typedef struct
 {
index e5a86f3496291db7d57bf0af1f68f6dfdebcd75a..352dae4ff9c1c3154586464d2cacf72a27dda955 100644 (file)
@@ -286,7 +286,6 @@ typedef struct {
 typedef struct {
        MonoMarshalByRefObject object;
        gpointer     handle;
-       MonoBoolean  disposed;
 } MonoWaitHandle;
 
 /* This is a copy of System.Runtime.Remoting.Messaging.CallType */
index d1178cc1b78e8d991d19b35604b32e07145aa281..fdb00751ccd909b2f7fcbfac24451c47f8e9b6ba 100644 (file)
@@ -6604,23 +6604,16 @@ mono_wait_handle_get_handle (MonoWaitHandle *handle)
 {
        MONO_REQ_GC_UNSAFE_MODE;
 
-       static MonoClassField *f_os_handle;
-       static MonoClassField *f_safe_handle;
+       static MonoClassField *f_safe_handle = NULL;
+       MonoSafeHandle *sh;
 
-       if (!f_os_handle && !f_safe_handle) {
-               f_os_handle = mono_class_get_field_from_name (mono_defaults.manualresetevent_class, "os_handle");
-               f_safe_handle = mono_class_get_field_from_name (mono_defaults.manualresetevent_class, "safe_wait_handle");
+       if (!f_safe_handle) {
+               f_safe_handle = mono_class_get_field_from_name (mono_defaults.manualresetevent_class, "safeWaitHandle");
+               g_assert (f_safe_handle);
        }
 
-       if (f_os_handle) {
-               HANDLE retval;
-               mono_field_get_value ((MonoObject*)handle, f_os_handle, &retval);
-               return retval;
-       } else {
-               MonoSafeHandle *sh;
-               mono_field_get_value ((MonoObject*)handle, f_safe_handle, &sh);
-               return sh->handle;
-       }
+       mono_field_get_value ((MonoObject*)handle, f_safe_handle, &sh);
+       return sh->handle;
 }
 
 
index 86a01a481f359aa6d66197bdde3ed223877cddcf..b097a377fe6a957221c7fe24a493ba2717b65e87 100644 (file)
@@ -95,10 +95,10 @@ gboolean ves_icall_System_Threading_Events_ResetEvent_internal (HANDLE handle);
 void ves_icall_System_Threading_Events_CloseEvent_internal (HANDLE handle);
 HANDLE ves_icall_System_Threading_Events_OpenEvent_internal (MonoString *name, gint32 rights, gint32 *error);
 
-gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext);
+gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext);
 gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext);
-gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this_obj, HANDLE handle, gint32 ms, gboolean exitContext);
-gboolean ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, HANDLE toWait, gint32 ms, gboolean exitContext);
+gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gint32 ms, gboolean exitContext);
+gint32 ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, HANDLE toWait, gint32 ms, gboolean exitContext);
 
 MonoArray* ves_icall_System_Threading_Thread_ByteArrayToRootDomain (MonoArray *arr);
 MonoArray* ves_icall_System_Threading_Thread_ByteArrayToCurrentDomain (MonoArray *arr);
index 3c04b893353af7833b67fbbb70cc52f2f6a1c9aa..1cb5e238b4d94a10ed676668d4bd1f308122aa79 100644 (file)
@@ -1583,7 +1583,7 @@ mono_wait_uninterrupted (MonoInternalThread *thread, gboolean multiple, guint32
 }
 
 /* FIXME: exitContext isnt documented */
-gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext)
+gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms, gboolean exitContext)
 {
        HANDLE *handles;
        guint32 numhandles;
@@ -1616,15 +1616,7 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_
 
        g_free(handles);
 
-       if(ret==WAIT_FAILED) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       } else if(ret==WAIT_TIMEOUT) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       }
-       
-       return(TRUE);
+       return ret;
 }
 
 /* FIXME: exitContext isnt documented */
@@ -1676,7 +1668,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
 }
 
 /* FIXME: exitContext isnt documented */
-gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this_obj, HANDLE handle, gint32 ms, gboolean exitContext)
+gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gint32 ms, gboolean exitContext)
 {
        guint32 ret;
        MonoInternalThread *thread = mono_thread_internal_current ();
@@ -1695,18 +1687,10 @@ gboolean ves_icall_System_Threading_WaitHandle_WaitOne_internal(MonoObject *this
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
        
-       if(ret==WAIT_FAILED) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait failed", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       } else if(ret==WAIT_TIMEOUT) {
-               THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") Wait timed out", __func__, mono_native_thread_id_get ()));
-               return(FALSE);
-       }
-       
-       return(TRUE);
+       return ret;
 }
 
-gboolean
+gint32
 ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, HANDLE toWait, gint32 ms, gboolean exitContext)
 {
        guint32 ret;
@@ -1725,7 +1709,7 @@ ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, H
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
-       return  (!(ret == WAIT_TIMEOUT || ret == WAIT_IO_COMPLETION || ret == WAIT_FAILED));
+       return ret;
 }
 
 HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
index e86cdf9df091ca5226d28752ac9ecbf35ee6db65..223dac2e7f6edcb4ec6848e00c16e177388a4713 100755 (executable)
@@ -1,2 +1,3 @@
 #!/bin/sh
+echo "Note: dmcs is deprecated, please use mcs instead!"
 exec @bindir@/mono $MONO_OPTIONS @mono_instdir@/4.5/mcs.exe -sdk:4.0 "$@"