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:
parent
bc19beadbd
commit
82351168b3
@ -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)
|
||||||
|
|||||||
@ -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));
|
||||||
|
|
||||||
|
|||||||
@ -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_ */
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user