/* The return value is only valid until a matching mono_thread_info_resume is called */ static MonoThreadInfo* suspend_sync (MonoNativeThreadId tid, gboolean interrupt_kernel) { MonoThreadHazardPointers *hp = mono_hazard_pointer_get (); MonoThreadInfo *info = mono_thread_info_lookup (tid); /*info on HP1*/ if (!info) return NULL; switch (mono_threads_transition_request_async_suspension (info)) { case AsyncSuspendAlreadySuspended: mono_hazard_pointer_clear (hp, 1); //XXX this is questionable we got to clean the suspend/resume nonsense of critical sections return info; case AsyncSuspendWait: mono_threads_add_to_pending_operation_set (info); break; case AsyncSuspendInitSuspend: if (!begin_async_suspend (info, interrupt_kernel)) { mono_hazard_pointer_clear (hp, 1); return NULL; } } //Wait for the pending suspend to finish mono_threads_wait_pending_operations (); if (!check_async_suspend (info)) { mono_hazard_pointer_clear (hp, 1); return NULL; } return info; }
gboolean mono_thread_info_begin_suspend (MonoThreadInfo *info, gboolean interrupt_kernel) { switch (mono_threads_transition_request_async_suspension (info)) { case AsyncSuspendAlreadySuspended: return TRUE; case AsyncSuspendWait: mono_threads_add_to_pending_operation_set (info); return TRUE; case AsyncSuspendInitSuspend: return mono_threads_core_begin_async_suspend (info, interrupt_kernel); default: g_assert_not_reached (); } }
gboolean mono_thread_info_begin_suspend (MonoThreadInfo *info) { switch (mono_threads_transition_request_async_suspension (info)) { case AsyncSuspendAlreadySuspended: case AsyncSuspendBlocking: return TRUE; case AsyncSuspendWait: mono_threads_add_to_pending_operation_set (info); return TRUE; case AsyncSuspendInitSuspend: return begin_async_suspend (info, FALSE); default: g_assert_not_reached (); } }