[threads] Make OSEvent alertable to fix bug #51653 (#4347)
[mono.git] / mono / metadata / threads.c
index 28b66c8eb3da13ed2d013971115376e0bbaf0628..99206e69f7db75b4a951fb63aec816450f9ad9ed 100644 (file)
@@ -699,7 +699,6 @@ mono_thread_attach_internal (MonoThread *thread, gboolean force_attach, gboolean
        }
 
        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");
        }
 
@@ -923,7 +922,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);
@@ -1569,13 +1567,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);
 
-       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.");
@@ -1586,8 +1586,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)
@@ -1612,7 +1611,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);
 }
 
@@ -5002,7 +5001,7 @@ 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;
 }
@@ -5085,7 +5084,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 {