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;
}
#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;
/* 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);
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;
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 */
worker_thread (gpointer data)
{
MonoThreadPoolWorker *worker;
- MonoError error;
MonoInternalThread *thread;
ThreadPoolWorkerCounter counter;
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;
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);
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);
}
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.");
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)
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);
}
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)
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;