win: lazy-load [GS]etThreadDescription symbols (#4679)

Said symbols are not by default available on Windows Server 2016 but
libuv can still use them when
api-ms-win-core-processthreads-l1-1-3.dll is present.

Fixes: https://github.com/libuv/libuv/issues/4677
This commit is contained in:
Ben Noordhuis 2025-01-24 21:53:22 +01:00 committed by GitHub
parent bc19beadbd
commit 82351168b3
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
3 changed files with 30 additions and 11 deletions

View File

@ -146,6 +146,8 @@ Threads
a thread name can be: Linux, IBM i (16), macOS (64), Windows (32767), and NetBSD (32), etc. `uv_thread_setname()` a thread name can be: Linux, IBM i (16), macOS (64), Windows (32767), and NetBSD (32), etc. `uv_thread_setname()`
will truncate it in case `name` is larger than the limit of the platform. will truncate it in case `name` is larger than the limit of the platform.
Not supported on Windows Server 2016, returns `UV_ENOSYS`.
.. versionadded:: 1.50.0 .. versionadded:: 1.50.0
.. c:function:: int uv_thread_getname(uv_thread_t* tid, char* name, size_t* size) .. c:function:: int uv_thread_getname(uv_thread_t* tid, char* name, size_t* size)
@ -155,6 +157,8 @@ Threads
The buffer should be large enough to hold the name of the thread plus the trailing NUL, or it will be truncated to fit The buffer should be large enough to hold the name of the thread plus the trailing NUL, or it will be truncated to fit
with the trailing NUL. with the trailing NUL.
Not supported on Windows Server 2016, returns `UV_ENOSYS`.
.. versionadded:: 1.50.0 .. versionadded:: 1.50.0
.. c:function:: int uv_thread_setpriority(uv_thread_t tid, int priority) .. c:function:: int uv_thread_setpriority(uv_thread_t tid, int priority)

View File

@ -57,6 +57,9 @@ STATIC_ASSERT(sizeof(uv_thread_t) <= sizeof(void*));
static uv_key_t uv__current_thread_key; static uv_key_t uv__current_thread_key;
static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT; static uv_once_t uv__current_thread_init_guard = UV_ONCE_INIT;
static uv_once_t uv__thread_name_once = UV_ONCE_INIT;
HRESULT (WINAPI *pGetThreadDescription)(HANDLE, PWSTR*);
HRESULT (WINAPI *pSetThreadDescription)(HANDLE, PCWSTR);
static void uv__init_current_thread_key(void) { static void uv__init_current_thread_key(void) {
@ -278,12 +281,28 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) {
} }
static void uv__thread_name_init_once(void) {
HMODULE m;
m = GetModuleHandleA("api-ms-win-core-processthreads-l1-1-3.dll");
if (m != NULL) {
pGetThreadDescription = (void*) GetProcAddress(m, "GetThreadDescription");
pSetThreadDescription = (void*) GetProcAddress(m, "SetThreadDescription");
}
}
int uv_thread_setname(const char* name) { int uv_thread_setname(const char* name) {
HRESULT hr; HRESULT hr;
WCHAR* namew; WCHAR* namew;
int err; int err;
char namebuf[UV_PTHREAD_MAX_NAMELEN_NP]; char namebuf[UV_PTHREAD_MAX_NAMELEN_NP];
uv_once(&uv__thread_name_once, uv__thread_name_init_once);
if (pSetThreadDescription == NULL)
return UV_ENOSYS;
if (name == NULL) if (name == NULL)
return UV_EINVAL; return UV_EINVAL;
@ -295,7 +314,7 @@ int uv_thread_setname(const char* name) {
if (err) if (err)
return err; return err;
hr = SetThreadDescription(GetCurrentThread(), namew); hr = pSetThreadDescription(GetCurrentThread(), namew);
uv__free(namew); uv__free(namew);
if (FAILED(hr)) if (FAILED(hr))
return uv_translate_sys_error(HRESULT_CODE(hr)); return uv_translate_sys_error(HRESULT_CODE(hr));
@ -312,6 +331,11 @@ int uv_thread_getname(uv_thread_t* tid, char* name, size_t size) {
int r; int r;
DWORD exit_code; DWORD exit_code;
uv_once(&uv__thread_name_once, uv__thread_name_init_once);
if (pGetThreadDescription == NULL)
return UV_ENOSYS;
if (name == NULL || size == 0) if (name == NULL || size == 0)
return UV_EINVAL; return UV_EINVAL;
@ -324,7 +348,7 @@ int uv_thread_getname(uv_thread_t* tid, char* name, size_t size) {
namew = NULL; namew = NULL;
thread_name = NULL; thread_name = NULL;
hr = GetThreadDescription(*tid, &namew); hr = pGetThreadDescription(*tid, &namew);
if (FAILED(hr)) if (FAILED(hr))
return uv_translate_sys_error(HRESULT_CODE(hr)); return uv_translate_sys_error(HRESULT_CODE(hr));

View File

@ -4828,13 +4828,4 @@ typedef int (WINAPI *uv_sGetHostNameW)
int); int);
extern uv_sGetHostNameW pGetHostNameW; extern uv_sGetHostNameW pGetHostNameW;
/* processthreadsapi.h */
#if defined(__MINGW32__)
WINBASEAPI
HRESULT WINAPI GetThreadDescription(HANDLE hThread,
PWSTR *ppszThreadDescription);
WINBASEAPI
HRESULT WINAPI SetThreadDescription(HANDLE hThread, PCWSTR lpThreadDescription);
#endif
#endif /* UV_WIN_WINAPI_H_ */ #endif /* UV_WIN_WINAPI_H_ */