void mono_threads_finish_blocking (void *cookie, void* stackdata) { static gboolean warned_about_bad_transition; MonoThreadInfo *info; if (!mono_threads_is_coop_enabled ()) return; info = cookie; if (!info) return; g_assert (info == mono_thread_info_current_unchecked ()); switch (mono_threads_transition_done_blocking (info)) { case DoneBlockingAborted: if (!warned_about_bad_transition) { warned_about_bad_transition = TRUE; g_warning ("[%p] Blocking call ended in running state for, this might lead to unbound GC pauses.", mono_thread_info_get_tid (info)); } mono_threads_state_poll (); break; case DoneBlockingOk: info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE; break; case DoneBlockingWait: THREADS_SUSPEND_DEBUG ("state polling done, notifying of resume\n"); mono_thread_info_wait_for_resume (info); break; default: g_error ("Unknown thread state"); } }
void mono_threads_exit_gc_safe_region_unbalanced (gpointer cookie, gpointer *stackdata) { MonoThreadInfo *info; if (!mono_threads_is_coop_enabled ()) return; info = (MonoThreadInfo *)cookie; check_info (info, "exit", "safe"); switch (mono_threads_transition_done_blocking (info)) { case DoneBlockingOk: info->thread_saved_state [SELF_SUSPEND_STATE_INDEX].valid = FALSE; break; case DoneBlockingWait: THREADS_SUSPEND_DEBUG ("state polling done, notifying of resume\n"); mono_thread_info_wait_for_resume (info); break; default: g_error ("Unknown thread state"); } }