[io-layer] Extract GetThreadPriority and SetThreadPriority
[mono.git] / mono / io-layer / wait.c
index a91fff80d57c0697f6431d99b75fd9327a945433..7674aef01efc7f58f710cefea1bc15e1d5b6fd0b 100644 (file)
 #include <errno.h>
 
 #include <mono/io-layer/wapi.h>
-#include <mono/io-layer/handles-private.h>
 #include <mono/io-layer/wapi-private.h>
 #include <mono/io-layer/io-trace.h>
 #include <mono/utils/mono-logger-internals.h>
 #include <mono/utils/mono-time.h>
+#include <mono/utils/w32handle.h>
+#include <mono/utils/mono-threads.h>
 
 static gboolean own_if_signalled(gpointer handle)
 {
        gboolean ret = FALSE;
-       
-       if (_WAPI_SHARED_HANDLE (_wapi_handle_type (handle))) {
-               if (_wapi_handle_trylock_shared_handles () == EBUSY) {
-                       return (FALSE);
-               }
-       }
-       
-       if (_wapi_handle_issignalled (handle)) {
-               _wapi_handle_ops_own (handle);
-               ret = TRUE;
-       }
 
-       if (_WAPI_SHARED_HANDLE (_wapi_handle_type (handle))) {
-               _wapi_handle_unlock_shared_handles ();
+       if (mono_w32handle_issignalled (handle)) {
+               mono_w32handle_ops_own (handle);
+               ret = TRUE;
        }
 
        return(ret);
@@ -44,20 +35,10 @@ static gboolean own_if_signalled(gpointer handle)
 static gboolean own_if_owned(gpointer handle)
 {
        gboolean ret = FALSE;
-       
-       if (_WAPI_SHARED_HANDLE (_wapi_handle_type (handle))) {
-               if (_wapi_handle_trylock_shared_handles () == EBUSY) {
-                       return (FALSE);
-               }
-       }
-       
-       if (_wapi_handle_ops_isowned (handle)) {
-               _wapi_handle_ops_own (handle);
-               ret = TRUE;
-       }
 
-       if (_WAPI_SHARED_HANDLE (_wapi_handle_type (handle))) {
-               _wapi_handle_unlock_shared_handles ();
+       if (mono_w32handle_ops_isowned (handle)) {
+               mono_w32handle_ops_own (handle);
+               ret = TRUE;
        }
 
        return(ret);
@@ -88,20 +69,13 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
        guint32 ret, waited;
        int thr_ret;
        gboolean apc_pending = FALSE;
-       gpointer current_thread = wapi_get_current_thread_handle ();
-       gint64 now, end;
-       
-       if (current_thread == NULL) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(WAIT_FAILED);
-       }
+       gpointer current_thread;
+       gint64 wait_start, timeout_in_ticks;
+
+       current_thread = mono_thread_info_get_handle (mono_thread_info_current ());
 
        if (handle == _WAPI_THREAD_CURRENT) {
-               handle = wapi_get_current_thread_handle ();
-               if (handle == NULL) {
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return(WAIT_FAILED);
-               }
+               handle = current_thread;
        }
 
        if ((GPOINTER_TO_UINT (handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
@@ -109,22 +83,22 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
                return(WAIT_FAILED);
        }
        
-       if (_wapi_handle_test_capabilities (handle,
-                                           WAPI_HANDLE_CAP_WAIT) == FALSE) {
+       if (mono_w32handle_test_capabilities (handle,
+                                           MONO_W32HANDLE_CAP_WAIT) == FALSE) {
                MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p can't be waited for", __func__,
                           handle);
 
                return(WAIT_FAILED);
        }
 
-       _wapi_handle_ops_prewait (handle);
+       mono_w32handle_ops_prewait (handle);
        
-       if (_wapi_handle_test_capabilities (handle, WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
+       if (mono_w32handle_test_capabilities (handle, MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
                MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p has special wait", __func__, handle);
 
-               ret = _wapi_handle_ops_special_wait (handle, timeout, alertable);
+               ret = mono_w32handle_ops_specialwait (handle, timeout, alertable ? &apc_pending : NULL);
        
-               if (alertable && _wapi_thread_cur_apc_pending ())
+               if (apc_pending)
                        ret = WAIT_IO_COMPLETION;
 
                return ret;
@@ -133,11 +107,11 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
        
        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handle %p", __func__, handle);
 
-       thr_ret = _wapi_handle_lock_handle (handle);
+       thr_ret = mono_w32handle_lock_handle (handle);
        g_assert (thr_ret == 0);
 
-       if (_wapi_handle_test_capabilities (handle,
-                                           WAPI_HANDLE_CAP_OWN) == TRUE) {
+       if (mono_w32handle_test_capabilities (handle,
+                                           MONO_W32HANDLE_CAP_OWN) == TRUE) {
                if (own_if_owned (handle) == TRUE) {
                        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already owned", __func__,
                                   handle);
@@ -159,13 +133,15 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
                goto done;
        }
        
-       if (timeout != INFINITE)
-               end = mono_100ns_ticks () + timeout * 1000 * 10;
+       if (timeout != INFINITE) {
+               wait_start = mono_100ns_ticks ();
+               timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
+       }
 
        do {
                /* Check before waiting on the condition, just in case
                 */
-               _wapi_handle_ops_prewait (handle);
+               mono_w32handle_ops_prewait (handle);
 
                if (own_if_signalled (handle)) {
                        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__,
@@ -176,15 +152,15 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout,
                }
 
                if (timeout == INFINITE) {
-                       waited = _wapi_handle_timedwait_signal_handle (handle, INFINITE, alertable, FALSE, &apc_pending);
+                       waited = mono_w32handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &apc_pending : NULL);
                } else {
-                       now = mono_100ns_ticks ();
-                       if (end < now) {
+                       gint64 elapsed = mono_100ns_ticks () - wait_start;
+                       if (elapsed >= timeout_in_ticks) {
                                ret = WAIT_TIMEOUT;
                                goto done;
                        }
 
-                       waited = _wapi_handle_timedwait_signal_handle (handle, (end - now) / 10 / 1000, alertable, FALSE, &apc_pending);
+                       waited = mono_w32handle_timedwait_signal_handle (handle, (timeout_in_ticks - elapsed) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL);
                }
 
                if(waited==0 && !apc_pending) {
@@ -214,7 +190,7 @@ done:
 
        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, handle);
        
-       thr_ret = _wapi_handle_unlock_handle (handle);
+       thr_ret = mono_w32handle_unlock_handle (handle);
        g_assert (thr_ret == 0);
 
        return(ret);
@@ -267,28 +243,17 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
        guint32 ret = 0, waited;
        int thr_ret;
        gboolean apc_pending = FALSE;
-       gpointer current_thread = wapi_get_current_thread_handle ();
-       gint64 now, end;
-       
-       if (current_thread == NULL) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(WAIT_FAILED);
-       }
+       gpointer current_thread;
+       gint64 wait_start, timeout_in_ticks;
+
+       current_thread = mono_thread_info_get_handle (mono_thread_info_current ());
 
        if (signal_handle == _WAPI_THREAD_CURRENT) {
-               signal_handle = wapi_get_current_thread_handle ();
-               if (signal_handle == NULL) {
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return(WAIT_FAILED);
-               }
+               signal_handle = current_thread;
        }
 
        if (wait == _WAPI_THREAD_CURRENT) {
-               wait = wapi_get_current_thread_handle ();
-               if (wait == NULL) {
-                       SetLastError (ERROR_INVALID_HANDLE);
-                       return(WAIT_FAILED);
-               }
+               wait = current_thread;
        }
 
        if ((GPOINTER_TO_UINT (signal_handle) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
@@ -301,19 +266,19 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
                return(WAIT_FAILED);
        }
        
-       if (_wapi_handle_test_capabilities (signal_handle,
-                                           WAPI_HANDLE_CAP_SIGNAL)==FALSE) {
+       if (mono_w32handle_test_capabilities (signal_handle,
+                                           MONO_W32HANDLE_CAP_SIGNAL)==FALSE) {
                return(WAIT_FAILED);
        }
        
-       if (_wapi_handle_test_capabilities (wait,
-                                           WAPI_HANDLE_CAP_WAIT)==FALSE) {
+       if (mono_w32handle_test_capabilities (wait,
+                                           MONO_W32HANDLE_CAP_WAIT)==FALSE) {
                return(WAIT_FAILED);
        }
 
-       _wapi_handle_ops_prewait (wait);
+       mono_w32handle_ops_prewait (wait);
        
-       if (_wapi_handle_test_capabilities (wait, WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
+       if (mono_w32handle_test_capabilities (wait, MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE) {
                g_warning ("%s: handle %p has special wait, implement me!!",
                           __func__, wait);
 
@@ -322,12 +287,12 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
 
        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handle %p", __func__, wait);
 
-       thr_ret = _wapi_handle_lock_handle (wait);
+       thr_ret = mono_w32handle_lock_handle (wait);
        g_assert (thr_ret == 0);
 
-       _wapi_handle_ops_signal (signal_handle);
+       mono_w32handle_ops_signal (signal_handle);
 
-       if (_wapi_handle_test_capabilities (wait, WAPI_HANDLE_CAP_OWN)==TRUE) {
+       if (mono_w32handle_test_capabilities (wait, MONO_W32HANDLE_CAP_OWN)==TRUE) {
                if (own_if_owned (wait)) {
                        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p already owned", __func__,
                                   wait);
@@ -343,13 +308,14 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
                goto done;
        }
 
-       if (timeout != INFINITE)
-               end = mono_100ns_ticks () + timeout * 1000 * 10;
-
+       if (timeout != INFINITE) {
+               wait_start = mono_100ns_ticks ();
+               timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
+       }
        do {
                /* Check before waiting on the condition, just in case
                 */
-               _wapi_handle_ops_prewait (wait);
+               mono_w32handle_ops_prewait (wait);
        
                if (own_if_signalled (wait)) {
                        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: handle %p signalled", __func__, wait);
@@ -359,15 +325,15 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait,
                }
 
                if (timeout == INFINITE) {
-                       waited = _wapi_handle_timedwait_signal_handle (wait, INFINITE, alertable, FALSE, &apc_pending);
+                       waited = mono_w32handle_timedwait_signal_handle (wait, INFINITE, FALSE, alertable ? &apc_pending : NULL);
                } else {
-                       now = mono_100ns_ticks ();
-                       if (end < now) {
+                       gint64 elapsed = mono_100ns_ticks () - wait_start;
+                       if (elapsed >= timeout_in_ticks) {
                                ret = WAIT_TIMEOUT;
                                goto done;
                        }
 
-                       waited = _wapi_handle_timedwait_signal_handle (wait, (end - now) / 10 / 1000, alertable, FALSE, &apc_pending);
+                       waited = mono_w32handle_timedwait_signal_handle (wait, (timeout_in_ticks - elapsed) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL);
                }
 
                if (waited==0 && !apc_pending) {
@@ -396,7 +362,7 @@ done:
 
        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handle %p", __func__, wait);
 
-       thr_ret = _wapi_handle_unlock_handle (wait);
+       thr_ret = mono_w32handle_unlock_handle (wait);
        g_assert (thr_ret == 0);
 
        return(ret);
@@ -411,7 +377,7 @@ static gboolean test_and_own (guint32 numobjects, gpointer *handles,
        
        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking handles", __func__);
        
-       done = _wapi_handle_count_signalled_handles (numobjects, handles,
+       done = mono_w32handle_count_signalled_handles (numobjects, handles,
                                                     waitall, count, lowest);
        if (done == TRUE) {
                if (waitall == TRUE) {
@@ -425,7 +391,7 @@ static gboolean test_and_own (guint32 numobjects, gpointer *handles,
        
        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking handles", __func__);
 
-       _wapi_handle_unlock_handles (numobjects, handles);
+       mono_w32handle_unlock_handles (numobjects, handles);
 
        return(done);
 }
@@ -469,18 +435,15 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
        guint i;
        guint32 ret;
        int thr_ret;
-       gpointer current_thread = wapi_get_current_thread_handle ();
+       gpointer current_thread;
        guint32 retval;
        gboolean poll;
        gpointer sorted_handles [MAXIMUM_WAIT_OBJECTS];
        gboolean apc_pending = FALSE;
-       gint64 now, end;
-       
-       if (current_thread == NULL) {
-               SetLastError (ERROR_INVALID_HANDLE);
-               return(WAIT_FAILED);
-       }
+       gint64 wait_start, timeout_in_ticks;
        
+       current_thread = mono_thread_info_get_handle (mono_thread_info_current ());
+
        if (numobjects > MAXIMUM_WAIT_OBJECTS) {
                MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Too many handles: %d", __func__, numobjects);
 
@@ -494,14 +457,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
        /* Check for duplicates */
        for (i = 0; i < numobjects; i++) {
                if (handles[i] == _WAPI_THREAD_CURRENT) {
-                       handles[i] = wapi_get_current_thread_handle ();
-                       
-                       if (handles[i] == NULL) {
-                               MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %d bogus", __func__, i);
-
-                               bogustype = TRUE;
-                               break;
-                       }
+                       handles[i] = current_thread;
                }
 
                if ((GPOINTER_TO_UINT (handles[i]) & _WAPI_PROCESS_UNHANDLED) == _WAPI_PROCESS_UNHANDLED) {
@@ -512,7 +468,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                        break;
                }
 
-               if (_wapi_handle_test_capabilities (handles[i], WAPI_HANDLE_CAP_WAIT) == FALSE) {
+               if (mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_WAIT) == FALSE) {
                        MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: Handle %p can't be waited for",
                                   __func__, handles[i]);
 
@@ -521,7 +477,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                }
 
                sorted_handles [i] = handles [i];
-               _wapi_handle_ops_prewait (handles[i]);
+               mono_w32handle_ops_prewait (handles[i]);
        }
 
        qsort (sorted_handles, numobjects, sizeof (gpointer), g_direct_equal);
@@ -546,7 +502,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
 
        poll = FALSE;
        for (i = 0; i < numobjects; ++i)
-               if (_wapi_handle_type (handles [i]) == WAPI_HANDLE_PROCESS || _WAPI_SHARED_HANDLE (_wapi_handle_type (handles[i]))) 
+               if (mono_w32handle_get_type (handles [i]) == MONO_W32HANDLE_PROCESS)
                        /* Can't wait for a process handle + another handle without polling */
                        poll = TRUE;
 
@@ -559,8 +515,10 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                return WAIT_TIMEOUT;
        }
 
-       if (timeout != INFINITE)
-               end = mono_100ns_ticks () + timeout * 1000 * 10;
+       if (timeout != INFINITE) {
+               wait_start = mono_100ns_ticks ();
+               timeout_in_ticks = (gint64)timeout * 10 * 1000; //can't overflow as timeout is 32bits
+       }
 
        /* Have to wait for some or all handles to become signalled
         */
@@ -570,7 +528,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                 * disappear from under us while we're waiting in the loop
                 * (not lock, as we don't want exclusive access here)
                 */
-               _wapi_handle_ref (handles[i]);
+               mono_w32handle_ref (handles[i]);
        }
 
        while(1) {
@@ -578,41 +536,41 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
                 * special-wait handles that aren't already signalled
                 */
                for (i = 0; i < numobjects; i++) {
-                       _wapi_handle_ops_prewait (handles[i]);
+                       mono_w32handle_ops_prewait (handles[i]);
                
-                       if (_wapi_handle_test_capabilities (handles[i], WAPI_HANDLE_CAP_SPECIAL_WAIT) == TRUE && _wapi_handle_issignalled (handles[i]) == FALSE) {
-                               _wapi_handle_ops_special_wait (handles[i], 0, alertable);
+                       if (mono_w32handle_test_capabilities (handles[i], MONO_W32HANDLE_CAP_SPECIAL_WAIT) == TRUE && mono_w32handle_issignalled (handles[i]) == FALSE) {
+                               mono_w32handle_ops_specialwait (handles[i], 0, alertable ? &apc_pending : NULL);
                        }
                }
                
                MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: locking signal mutex", __func__);
 
-               thr_ret = _wapi_handle_lock_signal_mutex ();
+               thr_ret = mono_w32handle_lock_signal_mutex ();
                g_assert (thr_ret == 0);
 
                /* Check the signalled state of handles inside the critical section */
                if (waitall) {
                        done = TRUE;
                        for (i = 0; i < numobjects; i++)
-                               if (!_wapi_handle_issignalled (handles [i]))
+                               if (!mono_w32handle_issignalled (handles [i]))
                                        done = FALSE;
                } else {
                        done = FALSE;
                        for (i = 0; i < numobjects; i++)
-                               if (_wapi_handle_issignalled (handles [i]))
+                               if (mono_w32handle_issignalled (handles [i]))
                                        done = TRUE;
                }
                
                if (!done) {
                        /* Enter the wait */
                        if (timeout == INFINITE) {
-                               ret = _wapi_handle_timedwait_signal (INFINITE, poll, &apc_pending);
+                               ret = mono_w32handle_timedwait_signal (INFINITE, poll, &apc_pending);
                        } else {
-                               now = mono_100ns_ticks ();
-                               if (end < now) {
+                               gint64 elapsed = mono_100ns_ticks () - wait_start;
+                               if (elapsed >= timeout_in_ticks) {
                                        ret = WAIT_TIMEOUT;
                                } else {
-                                       ret = _wapi_handle_timedwait_signal ((end - now) / 10 / 1000, poll, &apc_pending);
+                                       ret = mono_w32handle_timedwait_signal ((timeout_in_ticks - elapsed) / 10 / 1000, poll, &apc_pending);
                                }
                        }
                } else {
@@ -622,7 +580,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
 
                MONO_TRACE (G_LOG_LEVEL_DEBUG, MONO_TRACE_IO_LAYER, "%s: unlocking signal mutex", __func__);
 
-               thr_ret = _wapi_handle_unlock_signal_mutex (NULL);
+               thr_ret = mono_w32handle_unlock_signal_mutex ();
                g_assert (thr_ret == 0);
                
                if (alertable && apc_pending) {
@@ -657,7 +615,7 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles,
 
        for (i = 0; i < numobjects; i++) {
                /* Unref everything we reffed above */
-               _wapi_handle_unref (handles[i]);
+               mono_w32handle_unref (handles[i]);
        }
 
        return retval;