aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorSantiago Gimeno <santiago.gimeno@gmail.com>2024-11-27 12:52:18 +0100
committerGitHub <noreply@github.com>2024-11-27 12:52:18 +0100
commit61c966cf0b4b6b5fc44d5ab3678cf5d0caef249d (patch)
treeb40a8e28b1eb0b2c31e05bd16f682511619a544d /src
parentb7d07d78e976acc453c9ba8f8409650c2ad8a585 (diff)
downloadlibuv-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.c20
-rw-r--r--src/unix/internal.h2
-rw-r--r--src/unix/thread.c92
-rw-r--r--src/uv-common.h14
-rw-r--r--src/win/thread.c73
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;