static guint32 mono_alloc_static_data_slot (StaticDataInfo *static_data, guint32 size, guint32 align);
static gboolean mono_thread_resume (MonoInternalThread* thread);
static void async_abort_internal (MonoInternalThread *thread, gboolean install_async_abort);
-static void self_abort_internal (MonoError *error);
+static void self_abort_internal (void);
static void async_suspend_internal (MonoInternalThread *thread, gboolean interrupt);
static void self_suspend_internal (void);
THREAD_DEBUG (g_message ("%s: Sleeping for %d ms", __func__, ms));
- if (mono_thread_current_check_pending_interrupt ())
- return;
+ mono_thread_current_check_pending_interrupt ();
while (TRUE) {
gboolean alerted = FALSE;
if (alerted) {
MonoException* exc = mono_thread_execute_interruption ();
if (exc) {
- mono_set_pending_exception (exc);
- return;
+ mono_raise_exception (exc);
} else {
// FIXME: !INFINITE
if (ms != INFINITE)
MonoInternalThread *cur_thread = mono_thread_internal_current ();
gboolean ret;
- if (mono_thread_current_check_pending_interrupt ())
- return FALSE;
+ mono_thread_current_check_pending_interrupt ();
LOCK_THREAD (thread);
return(FALSE);
}
-#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;
-}
-
static gint32
-mono_wait_uninterrupted (MonoInternalThread *thread, guint32 numhandles, gpointer *handles, gboolean waitall, gint32 ms, MonoError *error)
+mono_wait_uninterrupted (MonoInternalThread *thread, gboolean multiple, guint32 numhandles, gpointer *handles, gboolean waitall, gint32 ms, gboolean alertable)
{
MonoException *exc;
guint32 ret;
gint32 diff_ms;
gint32 wait = ms;
- mono_error_init (error);
-
start = (ms == -1) ? 0 : mono_100ns_ticks ();
do {
MONO_ENTER_GC_SAFE;
- if (numhandles != 1)
- ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, TRUE);
+ if (multiple)
+ ret = WaitForMultipleObjectsEx (numhandles, handles, waitall, wait, alertable);
else
- ret = WaitForSingleObjectEx (handles [0], ms, TRUE);
+ ret = WaitForSingleObjectEx (handles [0], ms, alertable);
MONO_EXIT_GC_SAFE;
if (ret != WAIT_IO_COMPLETION)
break;
exc = mono_thread_execute_interruption ();
- if (exc) {
- mono_error_set_exception_instance (error, exc);
- break;
- }
+ if (exc)
+ mono_raise_exception (exc);
if (ms == -1)
continue;
gint32 ves_icall_System_Threading_WaitHandle_WaitAll_internal(MonoArray *mono_handles, gint32 ms)
{
- MonoError error;
HANDLE *handles;
guint32 numhandles;
guint32 ret;
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);
+ mono_thread_current_check_pending_interrupt ();
/* We fail in managed if the array has more than 64 elements */
numhandles = (guint32)mono_array_length(mono_handles);
}
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
-
- ret = mono_wait_uninterrupted (thread, numhandles, handles, TRUE, ms, &error);
+
+ ret = mono_wait_uninterrupted (thread, TRUE, numhandles, handles, TRUE, ms, TRUE);
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
g_free(handles);
- 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 ret == WAIT_FAILED ? 0x7fffffff : ret;
}
gint32 ves_icall_System_Threading_WaitHandle_WaitAny_internal(MonoArray *mono_handles, gint32 ms)
{
- MonoError error;
HANDLE handles [MAXIMUM_WAIT_OBJECTS];
uintptr_t numhandles;
guint32 ret;
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);
+ mono_thread_current_check_pending_interrupt ();
numhandles = mono_array_length(mono_handles);
if (numhandles > MAXIMUM_WAIT_OBJECTS)
- return map_native_wait_result_to_managed (WAIT_FAILED);
+ return WAIT_FAILED;
for(i = 0; i < numhandles; i++) {
waitHandle = mono_array_get(mono_handles, MonoObject*, i);
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
- ret = mono_wait_uninterrupted (thread, numhandles, handles, FALSE, ms, &error);
+ ret = mono_wait_uninterrupted (thread, TRUE, numhandles, handles, FALSE, ms, TRUE);
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
THREAD_WAIT_DEBUG (g_message ("%s: (%"G_GSIZE_FORMAT") returning %d", __func__, mono_native_thread_id_get (), ret));
- mono_error_set_pending_exception (&error);
/*
* These need to be here. See MSDN dos on WaitForMultipleObjects.
*/
if (ret >= WAIT_OBJECT_0 && ret <= WAIT_OBJECT_0 + numhandles - 1) {
- return map_native_wait_result_to_managed (ret - WAIT_OBJECT_0);
+ return ret - WAIT_OBJECT_0;
}
else if (ret >= WAIT_ABANDONED_0 && ret <= WAIT_ABANDONED_0 + numhandles - 1) {
- return map_native_wait_result_to_managed (ret - WAIT_ABANDONED_0);
+ return ret - WAIT_ABANDONED_0;
}
else {
/* WAIT_FAILED in waithandle.cs is different from WAIT_FAILED in Win32 API */
- return map_native_wait_result_to_managed (ret);
+ return ret == WAIT_FAILED ? 0x7fffffff : ret;
}
}
gint32 ves_icall_System_Threading_WaitHandle_WaitOne_internal(HANDLE handle, gint32 ms)
{
- MonoError error;
guint32 ret;
MonoInternalThread *thread = mono_thread_internal_current ();
ms=INFINITE;
}
- if (mono_thread_current_check_pending_interrupt ())
- return map_native_wait_result_to_managed (WAIT_FAILED);
+ mono_thread_current_check_pending_interrupt ();
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
- ret = mono_wait_uninterrupted (thread, 1, &handle, FALSE, ms, &error);
+ ret = mono_wait_uninterrupted (thread, FALSE, 1, &handle, FALSE, ms, TRUE);
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
-
- mono_error_set_pending_exception (&error);
- return map_native_wait_result_to_managed (ret == WAIT_FAILED);
+
+ /* WAIT_FAILED in waithandle.cs is different from WAIT_FAILED in Win32 API */
+ return ret == WAIT_FAILED ? 0x7fffffff : ret;
}
gint32
if (ms == -1)
ms = INFINITE;
- if (mono_thread_current_check_pending_interrupt ())
- return map_native_wait_result_to_managed (WAIT_FAILED);
+ mono_thread_current_check_pending_interrupt ();
mono_thread_set_state (thread, ThreadState_WaitSleepJoin);
mono_thread_clr_state (thread, ThreadState_WaitSleepJoin);
- return map_native_wait_result_to_managed (ret);
+ /* WAIT_FAILED in waithandle.cs is different from WAIT_FAILED in Win32 API */
+ return ret == WAIT_FAILED ? 0x7fffffff : ret;
}
HANDLE ves_icall_System_Threading_Mutex_CreateMutex_internal (MonoBoolean owned, MonoString *name, MonoBoolean *created)
}
}
-/**
- * mono_thread_current_check_pending_interrupt:
- *
- * Checks if there's a interruption request and set the pending exception if so.
- *
- * @returns true if a pending exception was set
- */
-gboolean
-mono_thread_current_check_pending_interrupt (void)
+void mono_thread_current_check_pending_interrupt ()
{
MonoInternalThread *thread = mono_thread_internal_current ();
gboolean throw_ = FALSE;
UNLOCK_THREAD (thread);
- if (throw_)
- mono_set_pending_exception (mono_get_exception_thread_interrupted ());
- return throw_;
+ if (throw_) {
+ mono_raise_exception (mono_get_exception_thread_interrupted ());
+ }
}
-static gboolean
-request_thread_abort (MonoInternalThread *thread, MonoObject *state)
+void
+ves_icall_System_Threading_Thread_Abort (MonoInternalThread *thread, MonoObject *state)
{
LOCK_THREAD (thread);
(thread->state & ThreadState_Stopped) != 0)
{
UNLOCK_THREAD (thread);
- return FALSE;
+ return;
}
if ((thread->state & ThreadState_Unstarted) != 0) {
thread->state |= ThreadState_Aborted;
UNLOCK_THREAD (thread);
- return FALSE;
+ return;
}
thread->state |= ThreadState_AbortRequested;
mono_thread_resume (thread);
UNLOCK_THREAD (thread);
- return TRUE;
-}
-
-void
-ves_icall_System_Threading_Thread_Abort (MonoInternalThread *thread, MonoObject *state)
-{
- if (!request_thread_abort (thread, state))
- return;
- if (thread == mono_thread_internal_current ()) {
- MonoError error;
- self_abort_internal (&error);
- mono_error_set_pending_exception (&error);
- } else {
+ if (thread == mono_thread_internal_current ())
+ self_abort_internal ();
+ else
async_abort_internal (thread, TRUE);
- }
-}
-
-/**
- * mono_thread_internal_abort:
- *
- * Request thread @thread to be aborted.
- *
- * @thread MUST NOT be the current thread.
- */
-void
-mono_thread_internal_abort (MonoInternalThread *thread)
-{
- g_assert (thread != mono_thread_internal_current ());
-
- if (!request_thread_abort (thread, NULL))
- return;
- async_abort_internal (thread, TRUE);
}
void
return found;
}
-static gboolean
-request_thread_stop (MonoInternalThread *thread)
+void mono_thread_internal_stop (MonoInternalThread *thread)
{
LOCK_THREAD (thread);
(thread->state & ThreadState_Stopped) != 0)
{
UNLOCK_THREAD (thread);
- return FALSE;
+ return;
}
/* Make sure the thread is awake */
thread->state &= ~ThreadState_AbortRequested;
UNLOCK_THREAD (thread);
- return TRUE;
-}
-
-/**
- * mono_thread_internal_stop:
- *
- * Request thread @thread to stop.
- *
- * @thread MUST NOT be the current thread.
- */
-void
-mono_thread_internal_stop (MonoInternalThread *thread)
-{
- g_assert (thread != mono_thread_internal_current ());
-
- if (!request_thread_stop (thread))
- return;
- async_abort_internal (thread, TRUE);
+ if (thread == mono_thread_internal_current ())
+ self_abort_internal ();
+ else
+ async_abort_internal (thread, TRUE);
}
void mono_thread_stop (MonoThread *thread)
{
- MonoInternalThread *internal = thread->internal_thread;
-
- if (!request_thread_stop (internal))
- return;
-
- if (internal == mono_thread_internal_current ()) {
- MonoError error;
- self_abort_internal (&error);
- /*
- This function is part of the embeding API and has no way to return the exception
- to be thrown. So what we do is keep the old behavior and raise the exception.
- */
- mono_error_raise_exception (&error);
- } else {
- async_abort_internal (internal, TRUE);
- }
+ mono_thread_internal_stop (thread->internal_thread);
}
gint8
if (user_data.wait.num > 0) {
/* Abort the threads outside the threads lock */
for (i = 0; i < user_data.wait.num; ++i)
- mono_thread_internal_abort (user_data.wait.threads [i]);
+ ves_icall_System_Threading_Thread_Abort (user_data.wait.threads [i], NULL);
/*
* We should wait for the threads either to abort, or to leave the
}
static void
-self_abort_internal (MonoError *error)
+self_abort_internal (void)
{
MonoException *exc;
- mono_error_init (error);
-
/* FIXME this is insanely broken, it doesn't cause interruption to happen synchronously
* since passing FALSE to mono_thread_request_interruption makes sure it returns NULL */
exc = mono_thread_request_interruption (TRUE);
if (exc)
- mono_error_set_exception_instance (error, exc);
- else
- mono_thread_info_self_interrupt ();
+ mono_raise_exception (exc);
+
+ mono_thread_info_self_interrupt ();
}
typedef struct {