diff options
author | Santiago Gimeno <santiago.gimeno@gmail.com> | 2024-11-27 12:52:18 +0100 |
---|---|---|
committer | GitHub <noreply@github.com> | 2024-11-27 12:52:18 +0100 |
commit | 61c966cf0b4b6b5fc44d5ab3678cf5d0caef249d (patch) | |
tree | b40a8e28b1eb0b2c31e05bd16f682511619a544d /src | |
parent | b7d07d78e976acc453c9ba8f8409650c2ad8a585 (diff) | |
download | libuv-61c966cf0b4b6b5fc44d5ab3678cf5d0caef249d.tar.gz libuv-61c966cf0b4b6b5fc44d5ab3678cf5d0caef249d.zip |
src: add uv_thread_set/getname() methods (#4599)
`uv_thread_setname()` sets the name of the current thread. Different
platforms define different limits on the max number of characters
a thread name can be: Linux, IBMi (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.
`uv_thread_getname()` gets the name of the thread specified by `tid`.
The thread name is copied into the buffer pointed to by `name`. The
`size` parameter specifies the size of the buffer pointed to by `name`.
The buffer should be large enough to hold the name of the thread plus
the trailing NUL, or it will be truncated to fit.
Diffstat (limited to 'src')
-rw-r--r-- | src/unix/darwin-proctitle.c | 20 | ||||
-rw-r--r-- | src/unix/internal.h | 2 | ||||
-rw-r--r-- | src/unix/thread.c | 92 | ||||
-rw-r--r-- | src/uv-common.h | 14 | ||||
-rw-r--r-- | src/win/thread.c | 73 |
5 files changed, 183 insertions, 18 deletions
diff --git a/src/unix/darwin-proctitle.c b/src/unix/darwin-proctitle.c index 5288083e..5e564297 100644 --- a/src/unix/darwin-proctitle.c +++ b/src/unix/darwin-proctitle.c @@ -33,25 +33,9 @@ #include "darwin-stub.h" #endif - -static int uv__pthread_setname_np(const char* name) { - char namebuf[64]; /* MAXTHREADNAMESIZE */ - int err; - - strncpy(namebuf, name, sizeof(namebuf) - 1); - namebuf[sizeof(namebuf) - 1] = '\0'; - - err = pthread_setname_np(namebuf); - if (err) - return UV__ERR(err); - - return 0; -} - - int uv__set_process_title(const char* title) { #if TARGET_OS_IPHONE - return uv__pthread_setname_np(title); + return uv__thread_setname(title); #else CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef, const char*, @@ -177,7 +161,7 @@ int uv__set_process_title(const char* title) { goto out; } - uv__pthread_setname_np(title); /* Don't care if it fails. */ + uv__thread_setname(title); /* Don't care if it fails. */ err = 0; out: diff --git a/src/unix/internal.h b/src/unix/internal.h index 698caf17..b1d2b217 100644 --- a/src/unix/internal.h +++ b/src/unix/internal.h @@ -327,6 +327,8 @@ void uv__prepare_close(uv_prepare_t* handle); void uv__process_close(uv_process_t* handle); void uv__stream_close(uv_stream_t* handle); void uv__tcp_close(uv_tcp_t* handle); +int uv__thread_setname(const char* name); +int uv__thread_getname(uv_thread_t* tid, char* name, size_t size); size_t uv__thread_stack_size(void); void uv__udp_close(uv_udp_t* handle); void uv__udp_finish_close(uv_udp_t* handle); diff --git a/src/unix/thread.c b/src/unix/thread.c index 4d6ddc2b..e51c2904 100644 --- a/src/unix/thread.c +++ b/src/unix/thread.c @@ -23,6 +23,9 @@ #include "internal.h" #include <pthread.h> +#ifdef __OpenBSD__ +#include <pthread_np.h> +#endif #include <assert.h> #include <errno.h> @@ -297,6 +300,18 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) { return pthread_equal(*t1, *t2); } +int uv_thread_setname(const char* name) { + if (name == NULL) + return UV_EINVAL; + return uv__thread_setname(name); +} + +int uv_thread_getname(uv_thread_t* tid, char* name, size_t size) { + if (name == NULL || size == 0) + return UV_EINVAL; + + return uv__thread_getname(tid, name, size); +} int uv_mutex_init(uv_mutex_t* mutex) { #if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK) @@ -881,3 +896,80 @@ void uv_key_set(uv_key_t* key, void* value) { if (pthread_setspecific(*key, value)) abort(); } + +#if defined(_AIX) || defined(__MVS__) || defined(__PASE__) +int uv__thread_setname(const char* name) { + return UV_ENOSYS; +} +#elif defined(__APPLE__) +int uv__thread_setname(const char* name) { + char namebuf[UV_PTHREAD_MAX_NAMELEN_NP]; + strncpy(namebuf, name, sizeof(namebuf) - 1); + namebuf[sizeof(namebuf) - 1] = '\0'; + int err = pthread_setname_np(namebuf); + if (err) + return UV__ERR(errno); + return 0; +} +#elif defined(__NetBSD__) +int uv__thread_setname(const char* name) { + char namebuf[UV_PTHREAD_MAX_NAMELEN_NP]; + strncpy(namebuf, name, sizeof(namebuf) - 1); + namebuf[sizeof(namebuf) - 1] = '\0'; + return UV__ERR(pthread_setname_np(pthread_self(), "%s", namebuf)); +} +#elif defined(__OpenBSD__) +int uv__thread_setname(const char* name) { + char namebuf[UV_PTHREAD_MAX_NAMELEN_NP]; + strncpy(namebuf, name, sizeof(namebuf) - 1); + namebuf[sizeof(namebuf) - 1] = '\0'; + pthread_set_name_np(pthread_self(), namebuf); + return 0; +} +#else +int uv__thread_setname(const char* name) { + char namebuf[UV_PTHREAD_MAX_NAMELEN_NP]; + strncpy(namebuf, name, sizeof(namebuf) - 1); + namebuf[sizeof(namebuf) - 1] = '\0'; + return UV__ERR(pthread_setname_np(pthread_self(), namebuf)); +} +#endif + +#if (defined(__ANDROID_API__) && __ANDROID_API__ < 26) || \ + defined(_AIX) || \ + defined(__MVS__) || \ + defined(__PASE__) +int uv__thread_getname(uv_thread_t* tid, char* name, size_t size) { + return UV_ENOSYS; +} +#elif defined(__OpenBSD__) +int uv__thread_getname(uv_thread_t* tid, char* name, size_t size) { + char thread_name[UV_PTHREAD_MAX_NAMELEN_NP]; + pthread_get_name_np(*tid, thread_name, sizeof(thread_name)); + strncpy(name, thread_name, size - 1); + name[size - 1] = '\0'; + return 0; +} +#elif defined(__APPLE__) +int uv__thread_getname(uv_thread_t* tid, char* name, size_t size) { + char thread_name[UV_PTHREAD_MAX_NAMELEN_NP]; + if (pthread_getname_np(*tid, thread_name, sizeof(thread_name)) != 0) + return UV__ERR(errno); + + strncpy(name, thread_name, size - 1); + name[size - 1] = '\0'; + return 0; +} +#else +int uv__thread_getname(uv_thread_t* tid, char* name, size_t size) { + int r; + char thread_name[UV_PTHREAD_MAX_NAMELEN_NP]; + r = pthread_getname_np(*tid, thread_name, sizeof(thread_name)); + if (r != 0) + return UV__ERR(r); + + strncpy(name, thread_name, size - 1); + name[size - 1] = '\0'; + return 0; +} +#endif diff --git a/src/uv-common.h b/src/uv-common.h index 4baede2e..10df1706 100644 --- a/src/uv-common.h +++ b/src/uv-common.h @@ -428,4 +428,18 @@ struct uv__loop_internal_fields_s { #endif /* __linux__ */ }; +#if defined(_WIN32) +# define UV_PTHREAD_MAX_NAMELEN_NP 32767 +#elif defined(__APPLE__) +# define UV_PTHREAD_MAX_NAMELEN_NP 64 +#elif defined(__NetBSD__) || defined(__illumos__) +# define UV_PTHREAD_MAX_NAMELEN_NP PTHREAD_MAX_NAMELEN_NP +#elif defined (__linux__) +# define UV_PTHREAD_MAX_NAMELEN_NP 16 +#elif defined(__FreeBSD__) || defined(__OpenBSD__) || defined(__DragonFly__) +# define UV_PTHREAD_MAX_NAMELEN_NP (MAXCOMLEN + 1) +#else +# define UV_PTHREAD_MAX_NAMELEN_NP 16 +#endif + #endif /* UV_COMMON_H_ */ diff --git a/src/win/thread.c b/src/win/thread.c index 28f5e6bf..0b4e71b9 100644 --- a/src/win/thread.c +++ b/src/win/thread.c @@ -278,6 +278,79 @@ int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2) { } +int uv_thread_setname(const char* name) { +#ifdef __MINGW32__ + return UV_ENOSYS; +#else + HRESULT hr; + WCHAR* namew; + int err; + char namebuf[UV_PTHREAD_MAX_NAMELEN_NP]; + + if (name == NULL) + return UV_EINVAL; + + strncpy(namebuf, name, sizeof(namebuf) - 1); + namebuf[sizeof(namebuf) - 1] = '\0'; + + namew = NULL; + err = uv__convert_utf8_to_utf16(namebuf, &namew); + if (err) + return err; + + hr = SetThreadDescription(GetCurrentThread(), namew); + uv__free(namew); + if (FAILED(hr)) + return uv_translate_sys_error(HRESULT_CODE(hr)); + + return 0; +#endif /* __MINGW32__ */ +} + + +int uv_thread_getname(uv_thread_t* tid, char* name, size_t size) { +#ifdef __MINGW32__ + return UV_ENOSYS; +#else + HRESULT hr; + WCHAR* namew; + char* thread_name; + size_t buf_size; + int r; + DWORD exit_code; + + if (name == NULL || size == 0) + return UV_EINVAL; + + if (tid == NULL || *tid == NULL) + return UV_EINVAL; + + /* Check if the thread handle is valid */ + if (!GetExitCodeThread(*tid, &exit_code) || exit_code != STILL_ACTIVE) + return UV_ENOENT; + + namew = NULL; + thread_name = NULL; + hr = GetThreadDescription(*tid, &namew); + if (FAILED(hr)) + return uv_translate_sys_error(HRESULT_CODE(hr)); + + buf_size = size; + r = uv__copy_utf16_to_utf8(namew, -1, name, &buf_size); + if (r == UV_ENOBUFS) { + r = uv__convert_utf16_to_utf8(namew, wcslen(namew), &thread_name); + if (r == 0) { + uv__strscpy(name, thread_name, size); + uv__free(thread_name); + } + } + + LocalFree(namew); + return r; +#endif /* __MINGW32__ */ +} + + int uv_mutex_init(uv_mutex_t* mutex) { InitializeCriticalSection(mutex); return 0; |