[io-layer] Extract WaitForSingleObjectEx, WaitForMultipleObjectsEx and SignalObjectAn...
authorLudovic Henry <ludovic@xamarin.com>
Mon, 28 Nov 2016 19:55:09 +0000 (14:55 -0500)
committerLudovic Henry <ludovic@xamarin.com>
Wed, 30 Nov 2016 18:09:59 +0000 (13:09 -0500)
mono/io-layer/Makefile.am
mono/io-layer/wait.c [deleted file]
mono/io-layer/wait.h
mono/io-layer/wapi-remap.h
mono/metadata/boehm-gc.c
mono/metadata/monitor.c
mono/metadata/threadpool-ms.c
mono/metadata/threads.c
mono/metadata/w32handle.h

index 934ed07b7293d62a3d769ac4e3146079a50aeb79..2262281abaa44afc65ff5fe7bf65fc7f2b77d7ed 100644 (file)
@@ -56,7 +56,6 @@ OTHER_SRC = \
        uglify.h                \
        versioninfo.c           \
        versioninfo.h           \
-       wait.c                  \
        wait.h                  \
        wapi_glob.h             \
        wapi_glob.c             \
diff --git a/mono/io-layer/wait.c b/mono/io-layer/wait.c
deleted file mode 100644 (file)
index b7ff468..0000000
+++ /dev/null
@@ -1,163 +0,0 @@
-/*
- * wait.c:  wait for handles to become signalled
- *
- * Author:
- *     Dick Porter (dick@ximian.com)
- *
- * (C) 2002-2006 Novell, Inc.
- */
-
-#include <config.h>
-#include <glib.h>
-#include <string.h>
-#include <errno.h>
-
-#include <mono/io-layer/wapi.h>
-#include <mono/io-layer/wapi-private.h>
-#include <mono/metadata/w32handle.h>
-
-/**
- * WaitForSingleObjectEx:
- * @handle: an object to wait for
- * @timeout: the maximum time in milliseconds to wait for
- * @alertable: if TRUE, the wait can be interrupted by an APC call
- *
- * This function returns when either @handle is signalled, or @timeout
- * ms elapses.  If @timeout is zero, the object's state is tested and
- * the function returns immediately.  If @timeout is %INFINITE, the
- * function waits forever.
- *
- * Return value: %WAIT_ABANDONED - @handle is a mutex that was not
- * released by the owning thread when it exited.  Ownership of the
- * mutex object is granted to the calling thread and the mutex is set
- * to nonsignalled.  %WAIT_OBJECT_0 - The state of @handle is
- * signalled.  %WAIT_TIMEOUT - The @timeout interval elapsed and
- * @handle's state is still not signalled.  %WAIT_FAILED - an error
- * occurred. %WAIT_IO_COMPLETION - the wait was ended by an APC.
- */
-guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, gboolean alertable)
-{
-       MonoW32HandleWaitRet ret;
-
-       ret = mono_w32handle_wait_one (handle, timeout, alertable);
-       if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
-               return WAIT_OBJECT_0;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_ABANDONED_0)
-               return WAIT_ABANDONED_0;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
-               return WAIT_IO_COMPLETION;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
-               return WAIT_TIMEOUT;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
-               return WAIT_FAILED;
-       else
-               g_error ("%s: unknown ret value %d", __func__, ret);
-}
-
-
-/**
- * SignalObjectAndWait:
- * @signal_handle: An object to signal
- * @wait: An object to wait for
- * @timeout: The maximum time in milliseconds to wait for
- * @alertable: Specifies whether the function returnes when the system
- * queues an I/O completion routine or an APC for the calling thread.
- *
- * Atomically signals @signal and waits for @wait to become signalled,
- * or @timeout ms elapses.  If @timeout is zero, the object's state is
- * tested and the function returns immediately.  If @timeout is
- * %INFINITE, the function waits forever.
- *
- * @signal can be a semaphore, mutex or event object.
- *
- * If @alertable is %TRUE and the system queues an I/O completion
- * routine or an APC for the calling thread, the function returns and
- * the thread calls the completion routine or APC function.  If
- * %FALSE, the function does not return, and the thread does not call
- * the completion routine or APC function.  A completion routine is
- * queued when the ReadFileEx() or WriteFileEx() function in which it
- * was specified has completed.  The calling thread is the thread that
- * initiated the read or write operation.  An APC is queued when
- * QueueUserAPC() is called.  Currently completion routines and APC
- * functions are not supported.
- *
- * Return value: %WAIT_ABANDONED - @wait is a mutex that was not
- * released by the owning thread when it exited.  Ownershop of the
- * mutex object is granted to the calling thread and the mutex is set
- * to nonsignalled.  %WAIT_IO_COMPLETION - the wait was ended by one
- * or more user-mode asynchronous procedure calls queued to the
- * thread.  %WAIT_OBJECT_0 - The state of @wait is signalled.
- * %WAIT_TIMEOUT - The @timeout interval elapsed and @wait's state is
- * still not signalled.  %WAIT_FAILED - an error occurred.
- */
-guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
-                           guint32 timeout, gboolean alertable)
-{
-       MonoW32HandleWaitRet ret;
-
-       ret = mono_w32handle_signal_and_wait (signal_handle, wait, timeout, alertable);
-       if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0)
-               return WAIT_OBJECT_0;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_ABANDONED_0)
-               return WAIT_ABANDONED_0;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
-               return WAIT_IO_COMPLETION;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
-               return WAIT_TIMEOUT;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
-               return WAIT_FAILED;
-       else
-               g_error ("%s: unknown ret value %d", __func__, ret);
-}
-
-/**
- * WaitForMultipleObjectsEx:
- * @numobjects: The number of objects in @handles. The maximum allowed
- * is %MAXIMUM_WAIT_OBJECTS.
- * @handles: An array of object handles.  Duplicates are not allowed.
- * @waitall: If %TRUE, this function waits until all of the handles
- * are signalled.  If %FALSE, this function returns when any object is
- * signalled.
- * @timeout: The maximum time in milliseconds to wait for.
- * @alertable: if TRUE, the wait can be interrupted by an APC call
- * 
- * This function returns when either one or more of @handles is
- * signalled, or @timeout ms elapses.  If @timeout is zero, the state
- * of each item of @handles is tested and the function returns
- * immediately.  If @timeout is %INFINITE, the function waits forever.
- *
- * Return value: %WAIT_OBJECT_0 to %WAIT_OBJECT_0 + @numobjects - 1 -
- * if @waitall is %TRUE, indicates that all objects are signalled.  If
- * @waitall is %FALSE, the return value minus %WAIT_OBJECT_0 indicates
- * the first index into @handles of the objects that are signalled.
- * %WAIT_ABANDONED_0 to %WAIT_ABANDONED_0 + @numobjects - 1 - if
- * @waitall is %TRUE, indicates that all objects are signalled, and at
- * least one object is an abandoned mutex object (See
- * WaitForSingleObject() for a description of abandoned mutexes.)  If
- * @waitall is %FALSE, the return value minus %WAIT_ABANDONED_0
- * indicates the first index into @handles of an abandoned mutex.
- * %WAIT_TIMEOUT - The @timeout interval elapsed and no objects in
- * @handles are signalled.  %WAIT_FAILED - an error occurred.
- * %WAIT_IO_COMPLETION - the wait was ended by an APC.
- */
-guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
-                                gboolean waitall, guint32 timeout,
-                                gboolean alertable)
-{
-       MonoW32HandleWaitRet ret;
-
-       ret = mono_w32handle_wait_multiple (handles, numobjects, waitall, timeout, alertable);
-       if (ret >= MONO_W32HANDLE_WAIT_RET_SUCCESS_0 && ret <= MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + numobjects - 1)
-               return WAIT_OBJECT_0 + (ret - MONO_W32HANDLE_WAIT_RET_SUCCESS_0);
-       else if (ret >= MONO_W32HANDLE_WAIT_RET_ABANDONED_0 && ret <= MONO_W32HANDLE_WAIT_RET_ABANDONED_0 + numobjects - 1)
-               return WAIT_ABANDONED_0 + (ret - MONO_W32HANDLE_WAIT_RET_ABANDONED_0);
-       else if (ret == MONO_W32HANDLE_WAIT_RET_ALERTED)
-               return WAIT_IO_COMPLETION;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT)
-               return WAIT_TIMEOUT;
-       else if (ret == MONO_W32HANDLE_WAIT_RET_FAILED)
-               return WAIT_FAILED;
-       else
-               g_error ("%s: unknown ret value %d", __func__, ret);
-}
-
index cbbf5d68203b93857d3da19886db35de93ef873e..b470c2d6f2323957a7fe622adc511c20beded5fa 100644 (file)
@@ -26,12 +26,5 @@ G_BEGIN_DECLS
 #define WAIT_TIMEOUT           STATUS_TIMEOUT
 #define WAIT_IO_COMPLETION     STATUS_USER_APC
 
-extern guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, 
-                                       gboolean alertable);
-extern guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
-                                  guint32 timeout, gboolean alertable);
-extern guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
-                                     gboolean waitall, guint32 timeout, gboolean alertable);
-
 G_END_DECLS
 #endif /* _WAPI_WAIT_H_ */
index b19465c7c68e0a12ca403bf774ff8019513e2649..c106ee767c1b00784944eb15a8b603d25fa71d97 100644 (file)
@@ -63,8 +63,5 @@
 #define GetFileVersionInfo wapi_GetFileVersionInfo 
 #define VerQueryValue wapi_VerQueryValue 
 #define VerLanguageName wapi_VerLanguageName 
-#define WaitForSingleObjectEx wapi_WaitForSingleObjectEx
-#define SignalObjectAndWait wapi_SignalObjectAndWait
-#define WaitForMultipleObjectsEx wapi_WaitForMultipleObjectsEx
 
 #endif /* __WAPI_REMAP_H__ */
index aed903cc6a91b1f7db483af69afb4c1f19a47eae..51c5eebb05656a3e9e2373d8c5d5bb2bb7fd11e5 100644 (file)
@@ -24,6 +24,7 @@
 #include <mono/metadata/runtime.h>
 #include <mono/metadata/handle.h>
 #include <mono/metadata/sgen-toggleref.h>
+#include <mono/metadata/w32handle.h>
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-logger-internals.h>
 #include <mono/utils/mono-memory-model.h>
index 1d9ff1b8acc251ee6fd5524232aa1edf35204b71..f11c9589b82fbcc5e629b281b71ecd9085426aff 100644 (file)
@@ -1294,7 +1294,7 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
        MonoThreadsSync *mon;
        HANDLE event;
        guint32 nest;
-       guint32 ret;
+       MonoW32HandleWaitRet ret;
        gboolean success = FALSE;
        gint32 regain;
        MonoInternalThread *thread = mono_thread_internal_current ();
@@ -1350,7 +1350,11 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
         * signalled before we wait, we still succeed.
         */
        MONO_ENTER_GC_SAFE;
-       ret = WaitForSingleObjectEx (event, ms, TRUE);
+#ifdef HOST_WIN32
+       ret = mono_w32handle_convert_wait_ret (WaitForSingleObjectEx (event, ms, TRUE), 1);
+#else
+       ret = mono_w32handle_wait_one (event, ms, TRUE);
+#endif /* HOST_WIN32 */
        MONO_EXIT_GC_SAFE;
 
        /* Reset the thread state fairly early, so we don't have to worry
@@ -1370,12 +1374,16 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
 
        LOCK_DEBUG (g_message ("%s: (%d) Regained %p lock %p", __func__, mono_thread_info_get_small_id (), obj, mon));
 
-       if (ret == WAIT_TIMEOUT) {
+       if (ret == MONO_W32HANDLE_WAIT_RET_TIMEOUT) {
                /* Poll the event again, just in case it was signalled
                 * while we were trying to regain the monitor lock
                 */
                MONO_ENTER_GC_SAFE;
-               ret = WaitForSingleObjectEx (event, 0, FALSE);
+#ifdef HOST_WIN32
+               ret = mono_w32handle_convert_wait_ret (WaitForSingleObjectEx (event, 0, FALSE), 1);
+#else
+               ret = mono_w32handle_wait_one (event, 0, FALSE);
+#endif /* HOST_WIN32 */
                MONO_EXIT_GC_SAFE;
        }
 
@@ -1389,7 +1397,7 @@ ves_icall_System_Threading_Monitor_Monitor_wait (MonoObject *obj, guint32 ms)
         * thread.
         */
        
-       if (ret == WAIT_OBJECT_0) {
+       if (ret == MONO_W32HANDLE_WAIT_RET_SUCCESS_0) {
                LOCK_DEBUG (g_message ("%s: (%d) Success", __func__, mono_thread_info_get_small_id ()));
                success = TRUE;
        } else {
index f042e1762949b76b69e0bbfcd94b85e20794c1e1..43444211fe408992915b70e36495a3c6dabe13e5 100644 (file)
@@ -1443,7 +1443,11 @@ mono_threadpool_ms_end_invoke (MonoAsyncResult *ares, MonoArray **out_args, Mono
                }
                mono_monitor_exit ((MonoObject*) ares);
                MONO_ENTER_GC_SAFE;
+#ifdef HOST_WIN32
                WaitForSingleObjectEx (wait_event, INFINITE, TRUE);
+#else
+               mono_w32handle_wait_one (wait_event, INFINITE, TRUE);
+#endif
                MONO_EXIT_GC_SAFE;
        }
 
index b0aad20a5c914e923ef9f208a00c1212332af85b..a779e4a07a416141300eedff89610d0f0d0297fb 100644 (file)
@@ -1664,17 +1664,29 @@ ves_icall_System_Threading_Thread_Join_internal(MonoThread *this_obj, int ms)
 #define MANAGED_WAIT_FAILED 0x7fffffff
 
 static gint32
-map_native_wait_result_to_managed (gint32 val)
-{
-       /* WAIT_FAILED in waithandle.cs is different from WAIT_FAILED in Win32 API */
-       return val == WAIT_FAILED ? MANAGED_WAIT_FAILED : val;
+map_native_wait_result_to_managed (MonoW32HandleWaitRet val, gsize numobjects)
+{
+       if (val >= MONO_W32HANDLE_WAIT_RET_SUCCESS_0 && val < MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + numobjects) {
+               return WAIT_OBJECT_0 + (val - MONO_W32HANDLE_WAIT_RET_SUCCESS_0);
+       } else if (val >= MONO_W32HANDLE_WAIT_RET_ABANDONED_0 && val < MONO_W32HANDLE_WAIT_RET_ABANDONED_0 + numobjects) {
+               return WAIT_ABANDONED_0 + (val - MONO_W32HANDLE_WAIT_RET_ABANDONED_0);
+       } else if (val == MONO_W32HANDLE_WAIT_RET_ALERTED) {
+               return WAIT_IO_COMPLETION;
+       } else if (val == MONO_W32HANDLE_WAIT_RET_TIMEOUT) {
+               return WAIT_TIMEOUT;
+       } else if (val == MONO_W32HANDLE_WAIT_RET_FAILED) {
+               /* WAIT_FAILED in waithandle.cs is different from WAIT_FAILED in Win32 API */
+               return MANAGED_WAIT_FAILED;
+       } else {
+               g_error ("%s: unknown val value %d", __func__, val);
+       }
 }
 
-static gint32
+static MonoW32HandleWaitRet
 mono_wait_uninterrupted (MonoInternalThread *thread, guint32 numhandles, gpointer *handles, gboolean waitall, gint32 ms, MonoError *error)
 {
        MonoException *exc;
-       guint32 ret;
+       MonoW32HandleWaitRet ret;
        gint64 start;
        gint32 diff_ms;
        gint32 wait = ms;
@@ -1684,13 +1696,18 @@ mono_wait_uninterrupted (MonoInternalThread *thread, guint32 numhandles, gpointe
        start = (ms == -1) ? 0 : mono_100ns_ticks ();
        do {
                MONO_ENTER_GC_SAFE;
+#ifdef HOST_WIN32
                if (numhandles != 1)
-                       ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, TRUE);
+                       ret = mono_w32handle_convert_wait_ret (WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, TRUE), numhandles);
                else
-                       ret = WaitForSingleObjectEx (handles [0], ms, TRUE);
+                       ret = mono_w32handle_convert_wait_ret (WaitForSingleObjectEx (handles [0], ms, TRUE), 1);
+#else
+               /* mono_w32handle_wait_multiple optimizes the case for numhandles == 1 */
+               ret = mono_w32handle_wait_multiple (handles, numhandles, waitall, wait, TRUE);
+#endif /* HOST_WIN32 */
                MONO_EXIT_GC_SAFE;
 
-               if (ret != WAIT_IO_COMPLETION)
+               if (ret != MONO_W32HANDLE_WAIT_RET_ALERTED)
                        break;
 
                exc = mono_thread_execute_interruption ();
@@ -1705,7 +1722,7 @@ mono_wait_uninterrupted (MonoInternalThread *thread, guint32 numhandles, gpointe
                /* Re-calculate ms according to the time passed */
                diff_ms = (gint32)((mono_100ns_ticks () - start) / 10000);
                if (diff_ms >= ms) {
-                       ret = WAIT_TIMEOUT;
+                       ret = MONO_W32HANDLE_WAIT_RET_TIMEOUT;
                        break;
                }
                wait = ms - diff_ms;
@@ -1719,14 +1736,14 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_ha
        MonoError error;
        HANDLE *handles;
        guint32 numhandles;
-       guint32 ret;
+       MonoW32HandleWaitRet ret;
        guint32 i;
        MonoObject *waitHandle;
        MonoInternalThread *thread = mono_thread_internal_current ();
 
        /* Do this WaitSleepJoin check before creating objects */
        if (mono_thread_current_check_pending_interrupt ())
-               return map_native_wait_result_to_managed (WAIT_FAILED);
+               return map_native_wait_result_to_managed (MONO_W32HANDLE_WAIT_RET_FAILED, 0);
 
        /* We fail in managed if the array has more than 64 elements */
        numhandles = (guint32)mono_array_length(mono_handles);
@@ -1751,8 +1768,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_ha
 
        mono_error_set_pending_exception (&error);
 
-       /* WAIT_FAILED in waithandle.cs is different from WAIT_FAILED in Win32 API */
-       return map_native_wait_result_to_managed (ret);
+       return map_native_wait_result_to_managed (ret, numhandles);
 }
 
 gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_handles, gint32 ms)
@@ -1760,18 +1776,18 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
        MonoError error;
        HANDLE handles [MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS];
        uintptr_t numhandles;
-       guint32 ret;
+       MonoW32HandleWaitRet ret;
        guint32 i;
        MonoObject *waitHandle;
        MonoInternalThread *thread = mono_thread_internal_current ();
 
        /* Do this WaitSleepJoin check before creating objects */
        if (mono_thread_current_check_pending_interrupt ())
-               return map_native_wait_result_to_managed (WAIT_FAILED);
+               return map_native_wait_result_to_managed (MONO_W32HANDLE_WAIT_RET_FAILED, 0);
 
        numhandles = mono_array_length(mono_handles);
        if (numhandles > MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS)
-               return map_native_wait_result_to_managed (WAIT_FAILED);
+               return map_native_wait_result_to_managed (MONO_W32HANDLE_WAIT_RET_FAILED, 0);
 
        for(i = 0; i < numhandles; i++) {       
                waitHandle = mono_array_get(mono_handles, MonoObject*, i);
@@ -1792,14 +1808,13 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_ha
 
        mono_error_set_pending_exception (&error);
 
-       /* WAIT_FAILED in waithandle.cs is different from WAIT_FAILED in Win32 API */
-       return map_native_wait_result_to_managed (ret);
+       return map_native_wait_result_to_managed (ret, numhandles);
 }
 
 gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gint32 ms)
 {
        MonoError error;
-       guint32 ret;
+       MonoW32HandleWaitRet ret;
        MonoInternalThread *thread = mono_thread_internal_current ();
 
        THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") waiting for %p, %d ms", __func__, mono_native_thread_id_get (), handle, ms));
@@ -1809,7 +1824,7 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gin
        }
        
        if (mono_thread_current_check_pending_interrupt ())
-               return map_native_wait_result_to_managed (WAIT_FAILED);
+               return map_native_wait_result_to_managed (MONO_W32HANDLE_WAIT_RET_FAILED, 0);
 
        mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
        
@@ -1818,30 +1833,34 @@ gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gin
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
        mono_error_set_pending_exception (&error);
-       return map_native_wait_result_to_managed (ret);
+       return map_native_wait_result_to_managed (ret, 1);
 }
 
 gint32
 ves_icall_System_Threading_WaitHandle_SignalAndWait_Internal (HANDLE toSignal, HANDLE toWait, gint32 ms)
 {
-       guint32 ret;
+       MonoW32HandleWaitRet ret;
        MonoInternalThread *thread = mono_thread_internal_current ();
 
        if (ms == -1)
                ms = INFINITE;
 
        if (mono_thread_current_check_pending_interrupt ())
-               return map_native_wait_result_to_managed (WAIT_FAILED);
+               return map_native_wait_result_to_managed (MONO_W32HANDLE_WAIT_RET_FAILED, 0);
 
        mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
        
        MONO_ENTER_GC_SAFE;
-       ret = SignalObjectAndWait (toSignal, toWait, ms, TRUE);
+#ifdef HOST_WIN32
+       ret = mono_w32handle_convert_wait_ret (SignalObjectAndWait (toSignal, toWait, ms, TRUE), 1);
+#else
+       ret = mono_w32handle_signal_and_wait (toSignal, toWait, ms, TRUE);
+#endif
        MONO_EXIT_GC_SAFE;
        
        mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
 
-       return map_native_wait_result_to_managed (ret);
+       return map_native_wait_result_to_managed (ret, 1);
 }
 
 gint32 ves_icall_System_Threading_Interlocked_Increment_Int (gint32 *location)
index ce7d76ec68824cebc75436a4399d38e2116dbd82..1416bf2479b77125b572d3de91da7222ae885f5e 100644 (file)
@@ -5,6 +5,10 @@
 #include <config.h>
 #include <glib.h>
 
+#ifdef HOST_WIN32
+#include <windows.h>
+#endif
+
 #ifndef INVALID_HANDLE_VALUE
 #define INVALID_HANDLE_VALUE (gpointer)-1
 #endif
@@ -41,10 +45,10 @@ typedef struct
 {
        void (*close)(gpointer handle, gpointer data);
 
-       /* SignalObjectAndWait */
+       /* mono_w32handle_signal_and_wait */
        void (*signal)(gpointer signal);
 
-       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+       /* Called by mono_w32handle_wait_one and mono_w32handle_wait_multiple,
         * with the handle locked (shared handles aren't locked.)
         * Returns TRUE if ownership was established, false otherwise.
         * If TRUE, *statuscode contains a status code such as
@@ -52,20 +56,20 @@ typedef struct
         */
        gboolean (*own_handle)(gpointer handle, guint32 *statuscode);
 
-       /* Called by WaitForSingleObject and WaitForMultipleObjects, if the
+       /* Called by mono_w32handle_wait_one and mono_w32handle_wait_multiple, if the
         * handle in question is "ownable" (ie mutexes), to see if the current
         * thread already owns this handle
         */
        gboolean (*is_owned)(gpointer handle);
 
-       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+       /* Called by mono_w32handle_wait_one and mono_w32handle_wait_multiple,
         * if the handle in question needs a special wait function
         * instead of using the normal handle signal mechanism.
-        * Returns the WaitForSingleObject return code.
+        * Returns the mono_w32handle_wait_one return code.
         */
        MonoW32HandleWaitRet (*special_wait)(gpointer handle, guint32 timeout, gboolean *alerted);
 
-       /* Called by WaitForSingleObject and WaitForMultipleObjects,
+       /* Called by mono_w32handle_wait_one and mono_w32handle_wait_multiple,
         * if the handle in question needs some preprocessing before the
         * signal wait.
         */
@@ -159,4 +163,24 @@ mono_w32handle_wait_multiple (gpointer *handles, gsize nhandles, gboolean waital
 MonoW32HandleWaitRet
 mono_w32handle_signal_and_wait (gpointer signal_handle, gpointer wait_handle, guint32 timeout, gboolean alertable);
 
+#ifdef HOST_WIN32
+static inline MonoW32HandleWaitRet
+mono_w32handle_convert_wait_ret (guint32 res, guint32 numobjects)
+{
+       if (res >= WAIT_OBJECT_0 && res <= WAIT_OBJECT_0 + numobjects - 1)
+               return MONO_W32HANDLE_WAIT_RET_SUCCESS_0 + (res - WAIT_OBJECT_0);
+       else if (res >= WAIT_ABANDONED_0 && res <= WAIT_ABANDONED_0 + numobjects - 1)
+               return MONO_W32HANDLE_WAIT_RET_ABANDONED_0 + (res - WAIT_ABANDONED_0);
+       else if (res == WAIT_IO_COMPLETION)
+               return MONO_W32HANDLE_WAIT_RET_ALERTED;
+       else if (res == WAIT_TIMEOUT)
+               return MONO_W32HANDLE_WAIT_RET_TIMEOUT;
+       else if (res == WAIT_FAILED)
+               return MONO_W32HANDLE_WAIT_RET_FAILED;
+       else
+               g_error ("%s: unknown res value %d", __func__, res);
+}
+#endif
+
+
 #endif /* _MONO_METADATA_W32HANDLE_H_ */