[threads] Remove unused mono_thread_internal_stop (#4449)
[mono.git] / mono / metadata / threads.c
index bbbb9f69b88052bd30133aac0b262a525a511911..238abb9504cb949f0d247daefa9d7dca32bbc40d 100644 (file)
@@ -41,7 +41,6 @@
 #include <mono/utils/mono-tls.h>
 #include <mono/utils/atomic.h>
 #include <mono/utils/mono-memory-model.h>
-#include <mono/utils/mono-threads-coop.h>
 #include <mono/utils/mono-error-internals.h>
 #include <mono/utils/os-event.h>
 #include <mono/utils/mono-threads-debug.h>
@@ -49,7 +48,6 @@
 #include <mono/metadata/w32event.h>
 #include <mono/metadata/w32mutex.h>
 
-#include <mono/metadata/gc-internals.h>
 #include <mono/metadata/reflection-internals.h>
 #include <mono/metadata/abi-details.h>
 #include <mono/metadata/w32error.h>
@@ -208,7 +206,7 @@ static gboolean shutting_down = FALSE;
 static gint32 managed_thread_id_counter = 0;
 
 /* Class lazy loading functions */
-static GENERATE_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, System, AppDomainUnloadedException)
+static GENERATE_GET_CLASS_WITH_CACHE (appdomain_unloaded_exception, "System", "AppDomainUnloadedException")
 
 static void
 mono_threads_lock (void)
@@ -697,11 +695,11 @@ mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean
 
        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");
        }
 
@@ -917,7 +915,7 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
         */
        mono_threads_join_threads ();
 
-       mono_error_init (error);
+       error_init (error);
 
        mono_threads_lock ();
        if (shutting_down) {
@@ -925,7 +923,6 @@ create_thread (MonoThread *thread, MonoInternalThread *internal, MonoObject *sta
                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);
@@ -1021,7 +1018,7 @@ mono_thread_create_internal (MonoDomain *domain, gpointer func, gpointer arg, gb
        MonoInternalThread *internal;
        gboolean res;
 
-       mono_error_init (error);
+       error_init (error);
 
        internal = create_internal_thread_object ();
 
@@ -1553,7 +1550,7 @@ ves_icall_System_Threading_Thread_GetName_internal (MonoInternalThread *this_obj
        MonoError error;
        MonoString* str;
 
-       mono_error_init (&error);
+       error_init (&error);
 
        LOCK_THREAD (this_obj);
        
@@ -1571,13 +1568,15 @@ ves_icall_System_Threading_Thread_GetName_internal (MonoInternalThread *this_obj
 }
 
 void 
-mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, gboolean permanent, MonoError *error)
+mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, gboolean permanent, gboolean reset, MonoError *error)
 {
        LOCK_THREAD (this_obj);
 
-       mono_error_init (error);
+       error_init (error);
 
-       if ((this_obj->flags & MONO_THREAD_FLAG_NAME_SET)) {
+       if (reset) {
+               this_obj->flags &= ~MONO_THREAD_FLAG_NAME_SET;
+       } else if (this_obj->flags & MONO_THREAD_FLAG_NAME_SET) {
                UNLOCK_THREAD (this_obj);
                
                mono_error_set_invalid_operation (error, "Thread.Name can only be set once.");
@@ -1588,8 +1587,7 @@ mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, g
                this_obj->name_len = 0;
        }
        if (name) {
-               this_obj->name = g_new (gunichar2, mono_string_length (name));
-               memcpy (this_obj->name, mono_string_chars (name), mono_string_length (name) * 2);
+               this_obj->name = g_memdup (mono_string_chars (name), mono_string_length (name) * sizeof (gunichar2));
                this_obj->name_len = mono_string_length (name);
 
                if (permanent)
@@ -1614,7 +1612,7 @@ void
 ves_icall_System_Threading_Thread_SetName_internal (MonoInternalThread *this_obj, MonoString *name)
 {
        MonoError error;
-       mono_thread_set_name_internal (this_obj, name, TRUE, &error);
+       mono_thread_set_name_internal (this_obj, name, TRUE, FALSE, &error);
        mono_error_set_pending_exception (&error);
 }
 
@@ -1664,7 +1662,7 @@ byte_array_to_domain (MonoArray *arr, MonoDomain *domain, MonoError *error)
 {
        MonoArray *copy;
 
-       mono_error_init (error);
+       error_init (error);
        if (!arr)
                return NULL;
 
@@ -1745,7 +1743,7 @@ mono_join_uninterrupted (MonoThreadHandle* thread_to_join, gint32 ms, MonoError
        gint32 diff_ms;
        gint32 wait = ms;
 
-       mono_error_init (error);
+       error_init (error);
 
        start = (ms == -1) ? 0 : mono_msec_ticks ();
        for (;;) {
@@ -1854,7 +1852,7 @@ mono_wait_uninterrupted (MonoInternalThread *thread, guint32 numhandles, gpointe
        gint32 diff_ms;
        gint32 wait = ms;
 
-       mono_error_init (error);
+       error_init (error);
 
        start = (ms == -1) ? 0 : mono_100ns_ticks ();
        do {
@@ -2632,53 +2630,27 @@ is_running_protected_wrapper (void)
        return found;
 }
 
-static gboolean
-request_thread_stop (MonoInternalThread *thread)
+void
+mono_thread_stop (MonoThread *thread)
 {
-       LOCK_THREAD (thread);
+       MonoInternalThread *internal = thread->internal_thread;
 
-       if ((thread->state & ThreadState_StopRequested) != 0 ||
-               (thread->state & ThreadState_Stopped) != 0)
+       LOCK_THREAD (internal);
+
+       if (internal->state & (ThreadState_StopRequested | ThreadState_Stopped))
        {
-               UNLOCK_THREAD (thread);
-               return FALSE;
+               UNLOCK_THREAD (internal);
+               return;
        }
-       
-       /* Make sure the thread is awake */
-       mono_thread_resume (thread);
 
-       thread->state |= ThreadState_StopRequested;
-       thread->state &= ~ThreadState_AbortRequested;
-       
-       UNLOCK_THREAD (thread);
-       return TRUE;
-}
+       /* Make sure the internal is awake */
+       mono_thread_resume (internal);
 
-/**
- * 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);
-}
+       internal->state |= ThreadState_StopRequested;
+       internal->state &= ~ThreadState_AbortRequested;
 
-void mono_thread_stop (MonoThread *thread)
-{
-       MonoInternalThread *internal = thread->internal_thread;
+       UNLOCK_THREAD (internal);
 
-       if (!request_thread_stop (internal))
-               return;
-       
        if (internal == mono_thread_internal_current ()) {
                MonoError error;
                self_abort_internal (&error);
@@ -3211,22 +3183,21 @@ remove_and_abort_threads (gpointer key, gpointer value, gpointer user)
        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;
 }
 
 /** 
@@ -3664,7 +3635,7 @@ mono_threads_get_thread_dump (MonoArray **out_threads, MonoArray **out_stack_fra
        MonoDebugSourceLocation *location;
        int tindex, nthreads;
 
-       mono_error_init (error);
+       error_init (error);
        
        *out_threads = NULL;
        *out_stack_frames = NULL;
@@ -4847,13 +4818,6 @@ async_abort_critical (MonoThreadInfo *info, gpointer ud)
        if (mono_get_eh_callbacks ()->mono_install_handler_block_guard (mono_thread_info_get_suspend_state (info)))
                return MonoResumeThread;
 
-       /*
-       The target thread is running at least one protected block, which must not be interrupted, so we give up.
-       The protected block code will give them a chance when appropriate.
-       */
-       if (mono_thread_get_abort_prot_block_count (thread) > 0)
-               return MonoResumeThread;
-
        /*someone is already interrupting it*/
        if (!mono_thread_set_interruption_requested (thread))
                return MonoResumeThread;
@@ -4906,7 +4870,7 @@ self_abort_internal (MonoError *error)
 {
        MonoException *exc;
 
-       mono_error_init (error);
+       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 */
@@ -5004,11 +4968,33 @@ self_suspend_internal (void)
        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
@@ -5087,7 +5073,9 @@ mono_threads_join_threads (void)
                        if (thread != pthread_self ()) {
                                MONO_ENTER_GC_SAFE;
                                /* This shouldn't block */
+                               mono_threads_join_lock ();
                                mono_native_thread_join (thread);
+                               mono_threads_join_unlock ();
                                MONO_EXIT_GC_SAFE;
                        }
                } else {