if (shutting_down && !force_attach) {
mono_threads_unlock ();
+ mono_thread_pop_appdomain_ref ();
return FALSE;
}
if (!threads) {
- MONO_GC_REGISTER_ROOT_FIXED (threads, MONO_ROOT_SOURCE_THREADING, "threads table");
threads = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_VALUE_GC, MONO_ROOT_SOURCE_THREADING, "threads table");
}
return FALSE;
}
if (threads_starting_up == NULL) {
- MONO_GC_REGISTER_ROOT_FIXED (threads_starting_up, MONO_ROOT_SOURCE_THREADING, "starting threads table");
threads_starting_up = mono_g_hash_table_new_type (NULL, NULL, MONO_HASH_KEY_VALUE_GC, MONO_ROOT_SOURCE_THREADING, "starting threads table");
}
mono_g_hash_table_insert (threads_starting_up, thread, thread);
if (wait->num >= MONO_W32HANDLE_MAXIMUM_WAIT_OBJECTS)
return FALSE;
- /* The finalizer thread is not a background thread */
- if (!mono_native_thread_id_equals (thread_get_tid (thread), self)
- && (thread->state & ThreadState_Background) != 0
- && (thread->flags & MONO_THREAD_FLAG_DONT_MANAGE) == 0
- ) {
+ if (mono_native_thread_id_equals (thread_get_tid (thread), self))
+ return FALSE;
+ if (mono_gc_is_finalizer_internal_thread (thread))
+ return FALSE;
+
+ if ((thread->state & ThreadState_Background) && !(thread->flags & MONO_THREAD_FLAG_DONT_MANAGE)) {
wait->handles[wait->num] = mono_threads_open_thread_handle (thread->handle);
wait->threads[wait->num] = thread;
wait->num++;
THREAD_DEBUG (g_print ("%s: Aborting id: %"G_GSIZE_FORMAT"\n", __func__, (gsize)thread->tid));
mono_thread_internal_abort (thread);
- return TRUE;
}
- return !mono_native_thread_id_equals (thread_get_tid (thread), self)
- && !mono_gc_is_finalizer_internal_thread (thread);
+ return TRUE;
}
/**
event = thread->suspended;
MONO_ENTER_GC_SAFE;
- res = mono_os_event_wait_one (event, MONO_INFINITE_WAIT);
+ res = mono_os_event_wait_one (event, MONO_INFINITE_WAIT, TRUE);
g_assert (res == MONO_OS_EVENT_WAIT_RET_SUCCESS_0 || res == MONO_OS_EVENT_WAIT_RET_ALERTED);
MONO_EXIT_GC_SAFE;
}
+static void
+suspend_for_shutdown_async_call (gpointer unused)
+{
+ for (;;)
+ mono_thread_info_yield ();
+}
+
+static SuspendThreadResult
+suspend_for_shutdown_critical (MonoThreadInfo *info, gpointer unused)
+{
+ mono_thread_info_setup_async_call (info, suspend_for_shutdown_async_call, NULL);
+ return MonoResumeThread;
+}
+
+void
+mono_thread_internal_suspend_for_shutdown (MonoInternalThread *thread)
+{
+ g_assert (thread != mono_thread_internal_current ());
+
+ mono_thread_info_safe_suspend_and_run (thread_get_tid (thread), FALSE, suspend_for_shutdown_critical, NULL);
+}
+
/*
* mono_thread_is_foreign:
* @thread: the thread to query