Browse Source

util: fix race setting thread name on Win32

The call to set the thread name on Win32 platforms is done by the parent
thread, after _beginthreadex() returns. At this point the new child
thread is potentially already executing its start method. To ensure the
thread name is guaranteed to be set before any "interesting" code starts
executing, it must be done in the start method of the child thread itself.

Reviewed-by: Richard Henderson <richard.henderson@linaro.org>
Reviewed-by: Dr. David Alan Gilbert <dave@treblig.org>
Reviewed-by: Philippe Mathieu-Daudé <philmd@linaro.org>
Reviewed-by: Markus Armbruster <armbru@redhat.com>
Signed-off-by: Daniel P. Berrangé <berrange@redhat.com>
master
Daniel P. Berrangé 2 months ago
parent
commit
71d81b320d
  1. 15
      util/qemu-thread-win32.c

15
util/qemu-thread-win32.c

@ -22,6 +22,8 @@ typedef HRESULT (WINAPI *pSetThreadDescription) (HANDLE hThread,
static pSetThreadDescription SetThreadDescriptionFunc;
static HMODULE kernel32_module;
static void set_thread_description(const char *name);
static bool load_set_thread_description(void)
{
static gsize _init_once = 0;
@ -225,6 +227,7 @@ struct QemuThreadData {
void *arg;
short mode;
NotifierList exit;
char *name; /* Freed in win32_start_routine */
/* Only used for joinable threads. */
bool exited;
@ -266,6 +269,10 @@ static unsigned __stdcall win32_start_routine(void *arg)
void *(*start_routine)(void *) = data->start_routine;
void *thread_arg = data->arg;
if (data->name) {
set_thread_description(data->name);
g_clear_pointer(&data->name, g_free);
}
qemu_thread_data = data;
qemu_thread_exit(start_routine(thread_arg));
abort();
@ -316,7 +323,7 @@ void *qemu_thread_join(QemuThread *thread)
return ret;
}
static void set_thread_description(HANDLE h, const char *name)
static void set_thread_description(const char *name)
{
g_autofree wchar_t *namew = NULL;
@ -329,7 +336,7 @@ static void set_thread_description(HANDLE h, const char *name)
return;
}
SetThreadDescriptionFunc(h, namew);
SetThreadDescriptionFunc(GetCurrentThread(), namew);
}
void qemu_thread_create(QemuThread *thread, const char *name,
@ -344,6 +351,7 @@ void qemu_thread_create(QemuThread *thread, const char *name,
data->arg = arg;
data->mode = mode;
data->exited = false;
data->name = g_strdup(name);
notifier_list_init(&data->exit);
if (data->mode != QEMU_THREAD_DETACHED) {
@ -355,9 +363,6 @@ void qemu_thread_create(QemuThread *thread, const char *name,
if (!hThread) {
error_exit(GetLastError(), __func__);
}
if (name) {
set_thread_description(hThread, name);
}
CloseHandle(hThread);
thread->data = data;

Loading…
Cancel
Save