Skip to content

Commit

Permalink
[Mono] Don't set thread name of main thread on Linux
Browse files Browse the repository at this point in the history
Fixes dotnet/runtime#35908

Depends on dotnet/runtime#34064 (which has the test case)

This adds a new function `mono_native_thread_main_thread_known` which returns `TRUE` when the `MonoNativeThreadId` (`pthread_t` on Linux) of the main thread is known.  On Linux the main thread is the one where `gettid () == getpid ()`.  There are two complications:
1. `pthread_t` and `pid_t` are distinct tokens, so knowing the `pid_t` ("os id" in Mono) of the main thread doesn't tell us its `pthread_t` (`MonoNativeThreadId`)
2. In an embedding scenario, the main thread may never interact with Mono (for example all the calls to `mono_jit_init`, etc might be happening on a helper thread).
So the solution is to augment `register_thread` (responsible for initializing a `MonoThreadInfo`) to check for `getpid () == gettid()` and to save `pthread_self()` as the "main thread" when it becomes available.
  • Loading branch information
lambdageek committed May 12, 2020
1 parent 430570e commit 8ea6215
Show file tree
Hide file tree
Showing 3 changed files with 60 additions and 0 deletions.
9 changes: 9 additions & 0 deletions mono/utils/mono-threads-posix.c
Original file line number Diff line number Diff line change
Expand Up @@ -308,6 +308,15 @@ mono_native_thread_set_name (MonoNativeThreadId tid, const char *name)
pthread_setname_np (tid, "%s", (void*)n);
}
#elif defined (HAVE_PTHREAD_SETNAME_NP)
#if defined (__linux__)
/* Ignore requests to set the main thread name because it causes the
* value returned by Process.ProcessName to change.
*/
MonoNativeThreadId main_thread_tid;
if (mono_native_thread_id_main_thread_known (&main_thread_tid) &&
mono_native_thread_id_equals (tid, main_thread_tid))
return;
#endif
if (!name) {
pthread_setname_np (tid, "");
} else {
Expand Down
48 changes: 48 additions & 0 deletions mono/utils/mono-threads.c
Original file line number Diff line number Diff line change
Expand Up @@ -442,6 +442,53 @@ thread_handle_destroy (gpointer data)
g_free (thread_handle);
}

static gboolean native_thread_id_main_thread_known;
static MonoNativeThreadId native_thread_id_main_thread;

/**
* mono_native_thread_id_main_thread_known:
*
* If the main thread of the process has interacted with Mono (in the sense
* that it has a MonoThreadInfo associated with it), return \c TRUE and write
* its MonoNativeThreadId to \c main_thread_tid.
*
* Otherwise return \c FALSE.
*/
gboolean
mono_native_thread_id_main_thread_known (MonoNativeThreadId *main_thread_tid)
{
if (!native_thread_id_main_thread_known)
return FALSE;
g_assert (main_thread_tid);
*main_thread_tid = native_thread_id_main_thread;
return TRUE;
}

/*
* Saves the MonoNativeThreadId (on Linux pthread_t) of the current thread if
* it is the main thread.
*
* The main thread is (on Linux) the one whose OS thread id (on Linux pid_t) is
* equal to the process id.
*
* We have to do this at thread registration time because in embedding
* scenarios we can't count on the main thread to be the one that calls
* mono_jit_init, or other runtime initialization functions.
*/
static void
native_thread_set_main_thread (void)
{
if (native_thread_id_main_thread_known)
return;
#if defined(__linux__)
if (mono_native_thread_os_id_get () == (guint64)getpid ()) {
native_thread_id_main_thread = mono_native_thread_id_get ();
mono_memory_barrier ();
native_thread_id_main_thread_known = TRUE;
}
#endif
}

static gboolean
register_thread (MonoThreadInfo *info)
{
Expand All @@ -451,6 +498,7 @@ register_thread (MonoThreadInfo *info)

info->small_id = mono_thread_info_register_small_id ();
mono_thread_info_set_tid (info, mono_native_thread_id_get ());
native_thread_set_main_thread ();

info->handle = g_new0 (MonoThreadHandle, 1);
mono_refcount_init (info->handle, thread_handle_destroy);
Expand Down
3 changes: 3 additions & 0 deletions mono/utils/mono-threads.h
Original file line number Diff line number Diff line change
Expand Up @@ -643,6 +643,9 @@ void mono_threads_coop_end_global_suspend (void);
MONO_API MonoNativeThreadId
mono_native_thread_id_get (void);

gboolean
mono_native_thread_id_main_thread_known (MonoNativeThreadId *main_thread_tid);

/*
* This does _not_ return the same value as mono_native_thread_id_get, except on Windows.
* On POSIX, mono_native_thread_id_get returns the value from pthread_self, which is then
Expand Down

0 comments on commit 8ea6215

Please sign in to comment.