}
break;
case AsyncSuspendBlocking:
- if (interrupt_kernel && mono_threads_suspend_needs_abort_syscall ())
+ if (interrupt_kernel)
mono_threads_suspend_abort_syscall (info);
break;
void
mono_thread_info_setup_async_call (MonoThreadInfo *info, void (*target_func)(void*), void *user_data)
{
- /* An async call can only be setup on an async suspended thread */
- g_assert (mono_thread_info_run_state (info) == STATE_ASYNC_SUSPENDED);
+ if (!mono_threads_is_coop_enabled ()) {
+ /* In non-coop mode, an async call can only be setup on an async suspended thread, but in coop mode, a thread
+ * may be in blocking state, and will execute the async call when leaving the safepoint, leaving a gc safe
+ * region or entering a gc unsafe region */
+ g_assert (mono_thread_info_run_state (info) == STATE_ASYNC_SUSPENDED);
+ }
/*FIXME this is a bad assert, we probably should do proper locking and fail if one is already set*/
g_assert (!info->async_target);
info->async_target = target_func;
MonoThreadHazardPointers *hp;
MonoThreadInfo *info;
- if (tid == mono_native_thread_id_get () || !mono_threads_suspend_needs_abort_syscall ())
+ if (tid == mono_native_thread_id_get ())
return;
hp = mono_hazard_pointer_get ();
return FALSE;
}
-typedef struct {
- MonoRefCount ref;
- MonoThreadStart start_routine;
- gpointer start_routine_arg;
- MonoCoopSem registered;
- MonoThreadHandle *handle;
-} CreateThreadData;
-
-static void
-create_thread_data_destroy (gpointer data)
-{
- CreateThreadData *thread_data;
-
- thread_data = (CreateThreadData*) data;
-
- mono_coop_sem_destroy (&thread_data->registered);
- g_free (thread_data);
-}
-
-static gsize WINAPI
-inner_start_thread (gpointer data)
-{
- CreateThreadData *thread_data;
- MonoThreadInfo *info;
- MonoThreadStart start_routine;
- gpointer start_routine_arg;
- gsize start_routine_res;
- gsize dummy;
-
- thread_data = (CreateThreadData*) data;
- g_assert (thread_data);
-
- start_routine = thread_data->start_routine;
- start_routine_arg = thread_data->start_routine_arg;
-
- info = mono_thread_info_attach (&dummy);
- info->runtime_thread = TRUE;
-
- thread_data->handle = mono_threads_open_thread_handle (info->handle);
-
- mono_coop_sem_post (&thread_data->registered);
-
- mono_refcount_dec (thread_data);
-
- /* thread_data is not valid anymore */
- thread_data = NULL;
-
- /* Run the actual main function of the thread */
- start_routine_res = start_routine (start_routine_arg);
-
- mono_thread_info_exit (start_routine_res);
-
- g_assert_not_reached ();
-}
-
-/*
- * mono_threads_create_thread:
- *
- * Create a new thread executing START with argument ARG. Store its id into OUT_TID.
- * Returns: a windows or io-layer handle for the thread.
- */
-MonoThreadHandle*
-mono_threads_create_thread (MonoThreadStart start, gpointer arg, gsize * const stack_size, MonoNativeThreadId *out_tid)
-{
- CreateThreadData *thread_data;
- gint res;
- MonoThreadHandle *ret;
-
- thread_data = g_new0 (CreateThreadData, 1);
- mono_refcount_init (thread_data, create_thread_data_destroy);
- thread_data->start_routine = start;
- thread_data->start_routine_arg = arg;
- mono_coop_sem_init (&thread_data->registered, 0);
-
- res = mono_threads_platform_create_thread (inner_start_thread, (gpointer) mono_refcount_inc (thread_data), stack_size, out_tid);
- if (res != 0) {
- /* ref is not going to be decremented in inner_start_thread */
- mono_refcount_dec (thread_data);
- ret = NULL;
- goto done;
- }
-
- res = mono_coop_sem_wait (&thread_data->registered, MONO_SEM_FLAGS_NONE);
- g_assert (res == 0);
-
- ret = thread_data->handle;
- g_assert (ret);
-
-done:
- mono_refcount_dec (thread_data);
-
- return ret;
-}
-
/*
* mono_thread_info_get_stack_bounds:
*
{
MonoOSEventWaitRet res;
- res = mono_os_event_wait_one (&thread_handle->event, timeout);
+ res = mono_os_event_wait_one (&thread_handle->event, timeout, alertable);
if (res == MONO_OS_EVENT_WAIT_RET_SUCCESS_0)
return MONO_THREAD_INFO_WAIT_RET_SUCCESS_0;
else if (res == MONO_OS_EVENT_WAIT_RET_ALERTED)
if (background_change_event)
thread_events [nhandles ++] = background_change_event;
- res = mono_os_event_wait_multiple (thread_events, nhandles, waitall, timeout);
+ res = mono_os_event_wait_multiple (thread_events, nhandles, waitall, timeout, alertable);
if (res >= MONO_OS_EVENT_WAIT_RET_SUCCESS_0 && res <= MONO_OS_EVENT_WAIT_RET_SUCCESS_0 + nhandles - 1)
return MONO_THREAD_INFO_WAIT_RET_SUCCESS_0 + (res - MONO_OS_EVENT_WAIT_RET_SUCCESS_0);
else if (res == MONO_OS_EVENT_WAIT_RET_ALERTED)