From f0d003205cb21d5285bee596ffe1d7a90d326e7e Mon Sep 17 00:00:00 2001 From: Seungha Yang Date: Fri, 15 Jan 2021 01:16:34 +0900 Subject: [PATCH] task: Use SetThreadDescription Win32 API for setting thread name Since Windows 10 1607, we can make use of SetThreadDescription() API for setting thread name. Unlike previously used exception based method, this API will preserve configured thread name on dump file. Part-of: --- gst/gsttask.c | 60 +++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 58 insertions(+), 2 deletions(-) diff --git a/gst/gsttask.c b/gst/gsttask.c index 6c022fbdf8..f8df4268d2 100644 --- a/gst/gsttask.c +++ b/gst/gsttask.c @@ -112,6 +112,11 @@ struct _GstTaskPrivate #define WIN32_LEAN_AND_MEAN #include +typedef HRESULT (WINAPI * pSetThreadDescription) (HANDLE hThread, + PCWSTR lpThreadDescription); +static pSetThreadDescription SetThreadDescriptionFunc = NULL; +HMODULE kernel32_module = NULL; + struct _THREADNAME_INFO { DWORD dwType; // must be 0x1000 @@ -121,7 +126,7 @@ struct _THREADNAME_INFO }; typedef struct _THREADNAME_INFO THREADNAME_INFO; -void +static void SetThreadName (DWORD dwThreadID, LPCSTR szThreadName) { THREADNAME_INFO info; @@ -137,6 +142,57 @@ SetThreadName (DWORD dwThreadID, LPCSTR szThreadName) __except (EXCEPTION_CONTINUE_EXECUTION) { } } + +static gboolean +gst_task_win32_load_library (void) +{ + /* FIXME: Add support for UWP app */ +#if WINAPI_FAMILY_PARTITION(WINAPI_PARTITION_DESKTOP) + static volatile gsize _init_once = 0; + if (g_once_init_enter (&_init_once)) { + kernel32_module = LoadLibraryW (L"kernel32.dll"); + if (kernel32_module) { + SetThreadDescriptionFunc = + (pSetThreadDescription) GetProcAddress (kernel32_module, + "SetThreadDescription"); + if (!SetThreadDescriptionFunc) + FreeLibrary (kernel32_module); + } + g_once_init_leave (&_init_once, 1); + } +#endif + + return ! !SetThreadDescriptionFunc; +} + +static gboolean +gst_task_win32_set_thread_desc (const gchar * name) +{ + HRESULT hr; + wchar_t *namew; + + if (!gst_task_win32_load_library () || !name) + return FALSE; + + namew = g_utf8_to_utf16 (name, -1, NULL, NULL, NULL); + if (!namew) + return FALSE; + + hr = SetThreadDescriptionFunc (GetCurrentThread (), namew); + + g_free (namew); + return SUCCEEDED (hr); +} + +static void +gst_task_win32_set_thread_name (const gchar * name) +{ + /* Prefer SetThreadDescription over exception based way if available, + * since thread description set by SetThreadDescription will be preserved + * in dump file */ + if (!gst_task_win32_set_thread_desc (name)) + SetThreadName ((DWORD) - 1, name); +} #endif static void gst_task_finalize (GObject * object); @@ -265,7 +321,7 @@ gst_task_configure_name (GstTask * task) /* set the thread name to something easily identifiable */ GST_DEBUG_OBJECT (task, "Setting thread name to '%s'", name); - SetThreadName (-1, name); + gst_task_win32_set_thread_name (name); #endif }