X-Git-Url: http://wien.tomnetworks.com/gitweb/?a=blobdiff_plain;f=mono%2Fio-layer%2Fwait.c;h=7674aef01efc7f58f710cefea1bc15e1d5b6fd0b;hb=bd07ed29e07a93a9bd4fd819e8100d7130ea0cb3;hp=82a441ee3b8c71a792c3186fb6111db4be7f8a7a;hpb=69fd76078eb720a89f3420bab3fe1bc919896bec;p=mono.git diff --git a/mono/io-layer/wait.c b/mono/io-layer/wait.c index 82a441ee3b8..7674aef01ef 100644 --- a/mono/io-layer/wait.c +++ b/mono/io-layer/wait.c @@ -13,28 +13,20 @@ #include #include -#include #include #include #include +#include +#include +#include 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); @@ -43,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); @@ -87,19 +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 (); - - 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) { @@ -107,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; @@ -131,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); @@ -157,10 +133,15 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, goto done; } + 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__, @@ -170,7 +151,17 @@ guint32 WaitForSingleObjectEx(gpointer handle, guint32 timeout, goto done; } - waited = _wapi_handle_timedwait_signal_handle (handle, timeout, alertable, FALSE, &apc_pending); + if (timeout == INFINITE) { + waited = mono_w32handle_timedwait_signal_handle (handle, INFINITE, FALSE, alertable ? &apc_pending : NULL); + } else { + gint64 elapsed = mono_100ns_ticks () - wait_start; + if (elapsed >= timeout_in_ticks) { + ret = WAIT_TIMEOUT; + goto done; + } + + waited = mono_w32handle_timedwait_signal_handle (handle, (timeout_in_ticks - elapsed) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL); + } if(waited==0 && !apc_pending) { /* Condition was signalled, so hopefully @@ -199,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); @@ -252,27 +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 (); - - 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) { @@ -285,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); @@ -306,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); @@ -327,10 +308,14 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait, goto done; } + 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); @@ -339,7 +324,17 @@ guint32 SignalObjectAndWait(gpointer signal_handle, gpointer wait, goto done; } - waited = _wapi_handle_timedwait_signal_handle (wait, timeout, alertable, FALSE, &apc_pending); + if (timeout == INFINITE) { + waited = mono_w32handle_timedwait_signal_handle (wait, INFINITE, FALSE, alertable ? &apc_pending : NULL); + } else { + gint64 elapsed = mono_100ns_ticks () - wait_start; + if (elapsed >= timeout_in_ticks) { + ret = WAIT_TIMEOUT; + goto done; + } + + waited = mono_w32handle_timedwait_signal_handle (wait, (timeout_in_ticks - elapsed) / 10 / 1000, FALSE, alertable ? &apc_pending : NULL); + } if (waited==0 && !apc_pending) { /* Condition was signalled, so hopefully @@ -367,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); @@ -382,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) { @@ -396,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); } @@ -440,17 +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 wait_start, timeout_in_ticks; - if (current_thread == NULL) { - SetLastError (ERROR_INVALID_HANDLE); - return(WAIT_FAILED); - } - + 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); @@ -464,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) { @@ -482,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]); @@ -491,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); @@ -516,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; @@ -528,6 +514,12 @@ guint32 WaitForMultipleObjectsEx(guint32 numobjects, gpointer *handles, if (timeout == 0) { return WAIT_TIMEOUT; } + + 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 */ @@ -536,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) { @@ -544,34 +536,43 @@ 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 */ - ret = _wapi_handle_timedwait_signal (timeout, poll, &apc_pending); + if (timeout == INFINITE) { + ret = mono_w32handle_timedwait_signal (INFINITE, poll, &apc_pending); + } else { + gint64 elapsed = mono_100ns_ticks () - wait_start; + if (elapsed >= timeout_in_ticks) { + ret = WAIT_TIMEOUT; + } else { + ret = mono_w32handle_timedwait_signal ((timeout_in_ticks - elapsed) / 10 / 1000, poll, &apc_pending); + } + } } else { /* No need to wait */ ret = 0; @@ -579,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) { @@ -614,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;