#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);
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);
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) {
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;
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);
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__,
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
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);
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) {
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);
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);
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);
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
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);
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) {
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);
}
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);
/* 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) {
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]);
}
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);
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;
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
*/
* 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) {
* 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;
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) {
for (i = 0; i < numobjects; i++) {
/* Unref everything we reffed above */
- _wapi_handle_unref (handles[i]);
+ mono_w32handle_unref (handles[i]);
}
return retval;