[w32handle] Unify WaitHandle.Wait{One,Any,All} icalls (#5051)
[mono.git] / mcs / class / corlib / System.Threading / WaitHandle.cs
index f09b9fe7e551c33a006f27bf3fa1300258b73e04..0e16f046e8012a7fa5f1cbbb30a84877519e56b8 100644 (file)
@@ -45,8 +45,13 @@ namespace System.Threading
        {
                protected static readonly IntPtr InvalidHandle = (IntPtr) (-1);
 
+               internal const int MaxWaitHandles = 64;
+
                static int WaitMultiple(WaitHandle[] waitHandles, int millisecondsTimeout, bool exitContext, bool WaitAll)
                {
+                       if (waitHandles.Length > MaxWaitHandles)
+                               return WAIT_FAILED;
+
                        int release_last = -1;
 
                        try {
@@ -56,8 +61,7 @@ namespace System.Threading
 #endif
 
                                for (int i = 0; i < waitHandles.Length; ++i) {
-                                       try {
-                                       } finally {
+                                       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;
@@ -66,10 +70,14 @@ namespace System.Threading
                                        }
                                }
 
-                               if (WaitAll)
-                                       return WaitAll_internal (waitHandles, millisecondsTimeout);
-                               else
-                                       return WaitAny_internal (waitHandles, millisecondsTimeout);
+                               unsafe {
+                                       IntPtr* handles = stackalloc IntPtr[waitHandles.Length];
+
+                                       for (int i = 0; i < waitHandles.Length; ++i)
+                                               handles[i] = waitHandles[i].SafeWaitHandle.DangerousGetHandle ();
+
+                                       return Wait_internal(handles, waitHandles.Length, WaitAll, millisecondsTimeout);
+                               }
                        } finally {
                                for (int i = release_last; i >= 0; --i) {
                                        waitHandles [i].SafeWaitHandle.DangerousRelease ();
@@ -82,12 +90,6 @@ namespace System.Threading
                        }
                }
 
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private static extern int WaitAll_internal(WaitHandle[] handles, int ms);
-
-               [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               private static extern int WaitAny_internal(WaitHandle[] handles, int ms);
-
                static int WaitOneNative (SafeHandle waitableSafeHandle, uint millisecondsTimeout, bool hasThreadAffinity, bool exitContext)
                {
                        bool release = false;
@@ -99,7 +101,10 @@ namespace System.Threading
 
                                waitableSafeHandle.DangerousAddRef (ref release);
 
-                               return WaitOne_internal (waitableSafeHandle.DangerousGetHandle (), (int) millisecondsTimeout);
+                               unsafe {
+                                       IntPtr handle = waitableSafeHandle.DangerousGetHandle();
+                                       return Wait_internal(&handle, 1, false, (int)millisecondsTimeout);
+                               }
                        } finally {
                                if (release)
                                        waitableSafeHandle.DangerousRelease ();
@@ -112,7 +117,7 @@ namespace System.Threading
                }
 
                [MethodImplAttribute(MethodImplOptions.InternalCall)]
-               static extern int WaitOne_internal(IntPtr handle, int ms);
+               unsafe static extern int Wait_internal(IntPtr* handles, int numHandles, bool waitAll, int ms);
 
                static int SignalAndWaitOne (SafeWaitHandle waitHandleToSignal,SafeWaitHandle waitHandleToWaitOn, int millisecondsTimeout, bool hasThreadAffinity,  bool exitContext)
                {