From: Ludovic Henry Date: Thu, 9 Feb 2017 02:12:44 +0000 (-0500) Subject: [threads] Allow resetting the name of a threadpool thread (#4350) X-Git-Url: http://wien.tomnetworks.com/gitweb/?p=mono.git;a=commitdiff_plain;h=82bcac8efac8c2556cf748b062592a4fdc2ecc3e [threads] Allow resetting the name of a threadpool thread (#4350) Fixes bug https://bugzilla.xamarin.com/show_bug.cgi?id=47221 --- diff --git a/mcs/class/corlib/Test/System.Threading/ThreadTest.cs b/mcs/class/corlib/Test/System.Threading/ThreadTest.cs index 4c6694f1e17..ae5bdbfd586 100644 --- a/mcs/class/corlib/Test/System.Threading/ThreadTest.cs +++ b/mcs/class/corlib/Test/System.Threading/ThreadTest.cs @@ -13,6 +13,7 @@ using System; using System.Globalization; using System.Security.Principal; using System.Threading; +using System.Threading.Tasks; using System.Reflection; using System.Collections.Generic; using SD = System.Diagnostics; @@ -908,6 +909,25 @@ namespace MonoTests.System.Threading } #endif // MONO_FEATURE_MULTIPLE_APPDOMAINS + [Test] + public void SetNameInThreadPoolThread () + { + for (int i = 0; i < 10; ++i) { + Task t = Task.Run (delegate () { + Thread.CurrentThread.Name = "x/" + i; + Assert.AreEqual (Thread.CurrentThread.Name, "x/" + i, "#1"); + + try { + Thread.CurrentThread.Name = "y/" + i; + Assert.Fail ("#2"); + } catch (InvalidOperationException) { + } + }); + + t.Wait (); + } + } + void CheckIsRunning (string s, Thread t) { int c = counter; diff --git a/mono/metadata/appdomain.c b/mono/metadata/appdomain.c index 921aa7e2d61..819ce65616e 100644 --- a/mono/metadata/appdomain.c +++ b/mono/metadata/appdomain.c @@ -2486,7 +2486,7 @@ unload_thread_main (void *arg) /* Force it to be attached to avoid racing during shutdown. */ thread = mono_thread_attach_full (mono_get_root_domain (), TRUE); - mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Domain unloader"), TRUE, &error); + mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Domain unloader"), TRUE, FALSE, &error); if (!is_ok (&error)) { data->failure_reason = g_strdup (mono_error_get_message (&error)); mono_error_cleanup (&error); diff --git a/mono/metadata/attach.c b/mono/metadata/attach.c index d7c39797a66..1f2e0fd103d 100644 --- a/mono/metadata/attach.c +++ b/mono/metadata/attach.c @@ -506,7 +506,7 @@ receiver_thread (void *arg) printf ("attach: Connected.\n"); MonoThread *thread = mono_thread_attach (mono_get_root_domain ()); - mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Attach receiver"), TRUE, &error); + mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Attach receiver"), TRUE, FALSE, &error); mono_error_assert_ok (&error); /* Ask the runtime to not abort this thread */ //mono_thread_current ()->flags |= MONO_THREAD_FLAG_DONT_MANAGE; diff --git a/mono/metadata/gc.c b/mono/metadata/gc.c index fecd120d419..ffe0fd3a5cf 100644 --- a/mono/metadata/gc.c +++ b/mono/metadata/gc.c @@ -888,7 +888,7 @@ finalizer_thread (gpointer unused) MonoError error; gboolean wait = TRUE; - mono_thread_set_name_internal (mono_thread_internal_current (), mono_string_new (mono_get_root_domain (), "Finalizer"), FALSE, &error); + mono_thread_set_name_internal (mono_thread_internal_current (), mono_string_new (mono_get_root_domain (), "Finalizer"), FALSE, FALSE, &error); mono_error_assert_ok (&error); /* Register a hazard free queue pump callback */ diff --git a/mono/metadata/threadpool-worker-default.c b/mono/metadata/threadpool-worker-default.c index 6c499ebac9b..6e3a4b52130 100644 --- a/mono/metadata/threadpool-worker-default.c +++ b/mono/metadata/threadpool-worker-default.c @@ -546,7 +546,6 @@ static gsize WINAPI worker_thread (gpointer data) { MonoThreadPoolWorker *worker; - MonoError error; MonoInternalThread *thread; ThreadPoolWorkerCounter counter; @@ -567,9 +566,6 @@ worker_thread (gpointer data) g_ptr_array_add (worker->threads, thread); mono_coop_mutex_unlock (&worker->threads_lock); - mono_thread_set_name_internal (thread, mono_string_new (mono_get_root_domain (), "Threadpool worker"), FALSE, &error); - mono_error_assert_ok (&error); - while (!mono_runtime_is_shutting_down ()) { ThreadPoolWorkItem work_item; diff --git a/mono/metadata/threadpool.c b/mono/metadata/threadpool.c index e58a78d47e0..c1f0c1a12a9 100644 --- a/mono/metadata/threadpool.c +++ b/mono/metadata/threadpool.c @@ -422,6 +422,9 @@ worker_callback (gpointer unused) domains_unlock (); + mono_thread_set_name_internal (thread, mono_string_new (mono_get_root_domain (), "Threadpool worker"), FALSE, TRUE, &error); + mono_error_assert_ok (&error); + mono_thread_clr_state (thread, (MonoThreadState)~ThreadState_Background); if (!mono_thread_test_state (thread , ThreadState_Background)) ves_icall_System_Threading_Thread_SetState (thread, ThreadState_Background); diff --git a/mono/metadata/threads-types.h b/mono/metadata/threads-types.h index c473777932a..b562d2c8505 100644 --- a/mono/metadata/threads-types.h +++ b/mono/metadata/threads-types.h @@ -202,7 +202,7 @@ gunichar2* mono_thread_get_name (MonoInternalThread *this_obj, guint32 *name_len MONO_API MonoException* mono_thread_get_undeniable_exception (void); -void mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, gboolean permanent, MonoError *error); +void mono_thread_set_name_internal (MonoInternalThread *this_obj, MonoString *name, gboolean permanent, gboolean reset, MonoError *error); void mono_thread_suspend_all_other_threads (void); gboolean mono_threads_abort_appdomain_threads (MonoDomain *domain, int timeout); diff --git a/mono/metadata/threads.c b/mono/metadata/threads.c index b94a4ff7ff3..fe4365c29ba 100644 --- a/mono/metadata/threads.c +++ b/mono/metadata/threads.c @@ -1569,13 +1569,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 +1588,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 +1613,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); } diff --git a/mono/mini/aot-compiler.c b/mono/mini/aot-compiler.c index 701364be006..6e91638d881 100644 --- a/mono/mini/aot-compiler.c +++ b/mono/mini/aot-compiler.c @@ -7897,7 +7897,7 @@ compile_thread_main (gpointer user_data) MonoError error; MonoThread *thread = mono_thread_attach (domain); - mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "AOT compiler"), TRUE, &error); + mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "AOT compiler"), TRUE, FALSE, &error); mono_error_assert_ok (&error); for (i = 0; i < methods->len; ++i) diff --git a/mono/mini/debugger-agent.c b/mono/mini/debugger-agent.c index 11b7125b2b3..541b26e160a 100644 --- a/mono/mini/debugger-agent.c +++ b/mono/mini/debugger-agent.c @@ -10137,7 +10137,7 @@ debugger_thread (void *arg) debugger_thread_id = mono_native_thread_id_get (); MonoThread *thread = mono_thread_attach (mono_get_root_domain ()); - mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Debugger agent"), TRUE, &error); + mono_thread_set_name_internal (thread->internal_thread, mono_string_new (mono_get_root_domain (), "Debugger agent"), TRUE, FALSE, &error); mono_error_assert_ok (&error); thread->internal_thread->state |= ThreadState_Background;