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.
This commit is contained in:
parent
b7d07d78e9
commit
61c966cf0b
@ -667,6 +667,7 @@ if(LIBUV_BUILD_TESTS)
|
|||||||
test/test-thread-affinity.c
|
test/test-thread-affinity.c
|
||||||
test/test-thread-equal.c
|
test/test-thread-equal.c
|
||||||
test/test-thread.c
|
test/test-thread.c
|
||||||
|
test/test-thread-name.c
|
||||||
test/test-thread-priority.c
|
test/test-thread-priority.c
|
||||||
test/test-threadpool-cancel.c
|
test/test-threadpool-cancel.c
|
||||||
test/test-threadpool.c
|
test/test-threadpool.c
|
||||||
|
|||||||
@ -294,6 +294,7 @@ test_run_tests_SOURCES = test/blackhole-server.c \
|
|||||||
test/test-thread-equal.c \
|
test/test-thread-equal.c \
|
||||||
test/test-thread.c \
|
test/test-thread.c \
|
||||||
test/test-thread-affinity.c \
|
test/test-thread-affinity.c \
|
||||||
|
test/test-thread-name.c \
|
||||||
test/test-thread-priority.c \
|
test/test-thread-priority.c \
|
||||||
test/test-threadpool-cancel.c \
|
test/test-threadpool-cancel.c \
|
||||||
test/test-threadpool.c \
|
test/test-threadpool.c \
|
||||||
|
|||||||
@ -140,6 +140,23 @@ Threads
|
|||||||
.. c:function:: int uv_thread_join(uv_thread_t *tid)
|
.. c:function:: int uv_thread_join(uv_thread_t *tid)
|
||||||
.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)
|
.. c:function:: int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2)
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_setname(const char* name)
|
||||||
|
|
||||||
|
Sets the name of the current thread. Different platforms define different limits on the max number of characters
|
||||||
|
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.
|
||||||
|
|
||||||
|
.. versionadded:: 1.50.0
|
||||||
|
|
||||||
|
.. c:function:: int uv_thread_getname(uv_thread_t* tid, char* name, size_t* size)
|
||||||
|
|
||||||
|
Gets the name of the thread specified by `tid`. The thread name is copied, with the trailing NUL, 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
|
||||||
|
with the trailing NUL.
|
||||||
|
|
||||||
|
.. 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)
|
||||||
If the function succeeds, the return value is 0.
|
If the function succeeds, the return value is 0.
|
||||||
If the function fails, the return value is less than zero.
|
If the function fails, the return value is less than zero.
|
||||||
|
|||||||
@ -1900,6 +1900,9 @@ UV_EXTERN int uv_thread_getcpu(void);
|
|||||||
UV_EXTERN uv_thread_t uv_thread_self(void);
|
UV_EXTERN uv_thread_t uv_thread_self(void);
|
||||||
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
|
UV_EXTERN int uv_thread_join(uv_thread_t *tid);
|
||||||
UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2);
|
UV_EXTERN int uv_thread_equal(const uv_thread_t* t1, const uv_thread_t* t2);
|
||||||
|
UV_EXTERN int uv_thread_setname(const char* name);
|
||||||
|
UV_EXTERN int uv_thread_getname(uv_thread_t* tid, char* name, size_t size);
|
||||||
|
|
||||||
|
|
||||||
/* The presence of these unions force similar struct layout. */
|
/* The presence of these unions force similar struct layout. */
|
||||||
#define XX(_, name) uv_ ## name ## _t name;
|
#define XX(_, name) uv_ ## name ## _t name;
|
||||||
|
|||||||
@ -33,25 +33,9 @@
|
|||||||
#include "darwin-stub.h"
|
#include "darwin-stub.h"
|
||||||
#endif
|
#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) {
|
int uv__set_process_title(const char* title) {
|
||||||
#if TARGET_OS_IPHONE
|
#if TARGET_OS_IPHONE
|
||||||
return uv__pthread_setname_np(title);
|
return uv__thread_setname(title);
|
||||||
#else
|
#else
|
||||||
CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
CFStringRef (*pCFStringCreateWithCString)(CFAllocatorRef,
|
||||||
const char*,
|
const char*,
|
||||||
@ -177,7 +161,7 @@ int uv__set_process_title(const char* title) {
|
|||||||
goto out;
|
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;
|
err = 0;
|
||||||
|
|
||||||
out:
|
out:
|
||||||
|
|||||||
@ -327,6 +327,8 @@ void uv__prepare_close(uv_prepare_t* handle);
|
|||||||
void uv__process_close(uv_process_t* handle);
|
void uv__process_close(uv_process_t* handle);
|
||||||
void uv__stream_close(uv_stream_t* handle);
|
void uv__stream_close(uv_stream_t* handle);
|
||||||
void uv__tcp_close(uv_tcp_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);
|
size_t uv__thread_stack_size(void);
|
||||||
void uv__udp_close(uv_udp_t* handle);
|
void uv__udp_close(uv_udp_t* handle);
|
||||||
void uv__udp_finish_close(uv_udp_t* handle);
|
void uv__udp_finish_close(uv_udp_t* handle);
|
||||||
|
|||||||
@ -23,6 +23,9 @@
|
|||||||
#include "internal.h"
|
#include "internal.h"
|
||||||
|
|
||||||
#include <pthread.h>
|
#include <pthread.h>
|
||||||
|
#ifdef __OpenBSD__
|
||||||
|
#include <pthread_np.h>
|
||||||
|
#endif
|
||||||
#include <assert.h>
|
#include <assert.h>
|
||||||
#include <errno.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);
|
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) {
|
int uv_mutex_init(uv_mutex_t* mutex) {
|
||||||
#if defined(NDEBUG) || !defined(PTHREAD_MUTEX_ERRORCHECK)
|
#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))
|
if (pthread_setspecific(*key, value))
|
||||||
abort();
|
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
|
||||||
|
|||||||
@ -428,4 +428,18 @@ struct uv__loop_internal_fields_s {
|
|||||||
#endif /* __linux__ */
|
#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_ */
|
#endif /* UV_COMMON_H_ */
|
||||||
|
|||||||
@ -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) {
|
int uv_mutex_init(uv_mutex_t* mutex) {
|
||||||
InitializeCriticalSection(mutex);
|
InitializeCriticalSection(mutex);
|
||||||
return 0;
|
return 0;
|
||||||
|
|||||||
@ -478,6 +478,7 @@ TEST_DECLARE (thread_create)
|
|||||||
TEST_DECLARE (thread_equal)
|
TEST_DECLARE (thread_equal)
|
||||||
TEST_DECLARE (thread_affinity)
|
TEST_DECLARE (thread_affinity)
|
||||||
TEST_DECLARE (thread_priority)
|
TEST_DECLARE (thread_priority)
|
||||||
|
TEST_DECLARE (thread_name)
|
||||||
TEST_DECLARE (dlerror)
|
TEST_DECLARE (dlerror)
|
||||||
#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \
|
#if (defined(__unix__) || (defined(__APPLE__) && defined(__MACH__))) && \
|
||||||
!defined(__sun)
|
!defined(__sun)
|
||||||
@ -1193,6 +1194,7 @@ TASK_LIST_START
|
|||||||
TEST_ENTRY (thread_equal)
|
TEST_ENTRY (thread_equal)
|
||||||
TEST_ENTRY (thread_affinity)
|
TEST_ENTRY (thread_affinity)
|
||||||
TEST_ENTRY (thread_priority)
|
TEST_ENTRY (thread_priority)
|
||||||
|
TEST_ENTRY (thread_name)
|
||||||
TEST_ENTRY (dlerror)
|
TEST_ENTRY (dlerror)
|
||||||
TEST_ENTRY (ip4_addr)
|
TEST_ENTRY (ip4_addr)
|
||||||
TEST_ENTRY (ip6_addr_link_local)
|
TEST_ENTRY (ip6_addr_link_local)
|
||||||
|
|||||||
143
test/test-thread-name.c
Normal file
143
test/test-thread-name.c
Normal file
@ -0,0 +1,143 @@
|
|||||||
|
/* Copyright libuv project contributors. All rights reserved.
|
||||||
|
*
|
||||||
|
* Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
|
* of this software and associated documentation files (the "Software"), to
|
||||||
|
* deal in the Software without restriction, including without limitation the
|
||||||
|
* rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
|
||||||
|
* sell copies of the Software, and to permit persons to whom the Software is
|
||||||
|
* furnished to do so, subject to the following conditions:
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included in
|
||||||
|
* all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
|
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
|
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
|
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
|
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
|
||||||
|
* FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
|
||||||
|
* IN THE SOFTWARE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include "uv.h"
|
||||||
|
#include "task.h"
|
||||||
|
#include "../src/uv-common.h"
|
||||||
|
|
||||||
|
#include <string.h>
|
||||||
|
|
||||||
|
struct semaphores {
|
||||||
|
uv_sem_t main;
|
||||||
|
uv_sem_t worker;
|
||||||
|
};
|
||||||
|
|
||||||
|
static void thread_run(void* arg) {
|
||||||
|
int r;
|
||||||
|
char thread_name[16];
|
||||||
|
struct semaphores* sem;
|
||||||
|
uv_thread_t thread;
|
||||||
|
|
||||||
|
sem = arg;
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* uv_thread_self isn't defined for the main thread on Windows. */
|
||||||
|
thread = GetCurrentThread();
|
||||||
|
#else
|
||||||
|
thread = uv_thread_self();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
r = uv_thread_setname("worker-thread");
|
||||||
|
ASSERT_OK(r);
|
||||||
|
|
||||||
|
uv_sem_post(&sem->worker);
|
||||||
|
|
||||||
|
r = uv_thread_getname(&thread, thread_name, sizeof(thread_name));
|
||||||
|
ASSERT_OK(r);
|
||||||
|
|
||||||
|
ASSERT_STR_EQ(thread_name, "worker-thread");
|
||||||
|
|
||||||
|
uv_sem_wait(&sem->main);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_IMPL(thread_name) {
|
||||||
|
int r;
|
||||||
|
uv_thread_t threads[2];
|
||||||
|
char tn[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||||
|
char thread_name[UV_PTHREAD_MAX_NAMELEN_NP];
|
||||||
|
char long_thread_name[UV_PTHREAD_MAX_NAMELEN_NP + 1];
|
||||||
|
struct semaphores sem;
|
||||||
|
|
||||||
|
#if defined(__MINGW32__) || \
|
||||||
|
defined(__ANDROID_API__) && __ANDROID_API__ < 26 || \
|
||||||
|
defined(_AIX) || \
|
||||||
|
defined(__MVS__) || \
|
||||||
|
defined(__PASE__)
|
||||||
|
RETURN_SKIP("API not available on this platform");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ASSERT_OK(uv_sem_init(&sem.main, 0));
|
||||||
|
ASSERT_OK(uv_sem_init(&sem.worker, 0));
|
||||||
|
|
||||||
|
memset(thread_name, 'a', sizeof(thread_name) - 1);
|
||||||
|
thread_name[sizeof(thread_name) - 1] = '\0';
|
||||||
|
|
||||||
|
memset(long_thread_name, 'a', sizeof(long_thread_name) - 1);
|
||||||
|
long_thread_name[sizeof(long_thread_name) - 1] = '\0';
|
||||||
|
|
||||||
|
#ifdef _WIN32
|
||||||
|
/* uv_thread_self isn't defined for the main thread on Windows. */
|
||||||
|
threads[0] = GetCurrentThread();
|
||||||
|
#else
|
||||||
|
threads[0] = uv_thread_self();
|
||||||
|
#endif
|
||||||
|
|
||||||
|
r = uv_thread_getname(&threads[0], tn, sizeof(tn));
|
||||||
|
ASSERT_OK(r);
|
||||||
|
|
||||||
|
r = uv_thread_setname(long_thread_name);
|
||||||
|
ASSERT_OK(r);
|
||||||
|
|
||||||
|
r = uv_thread_getname(&threads[0], tn, sizeof(tn));
|
||||||
|
ASSERT_OK(r);
|
||||||
|
ASSERT_STR_EQ(tn, thread_name);
|
||||||
|
|
||||||
|
r = uv_thread_setname(thread_name);
|
||||||
|
ASSERT_OK(r);
|
||||||
|
|
||||||
|
r = uv_thread_getname(&threads[0], tn, sizeof(tn));
|
||||||
|
ASSERT_OK(r);
|
||||||
|
ASSERT_STR_EQ(tn, thread_name);
|
||||||
|
|
||||||
|
r = uv_thread_getname(&threads[0], tn, 3);
|
||||||
|
ASSERT_OK(r);
|
||||||
|
ASSERT_EQ(strlen(tn), 2);
|
||||||
|
ASSERT_OK(memcmp(thread_name, tn, 2));
|
||||||
|
|
||||||
|
/* Illumos doesn't support non-ASCII thread names. */
|
||||||
|
#ifndef __illumos__
|
||||||
|
r = uv_thread_setname("~½¬{½");
|
||||||
|
ASSERT_OK(r);
|
||||||
|
|
||||||
|
r = uv_thread_getname(&threads[0], tn, sizeof(tn));
|
||||||
|
ASSERT_OK(r);
|
||||||
|
ASSERT_STR_EQ(tn, "~½¬{½");
|
||||||
|
#endif
|
||||||
|
|
||||||
|
ASSERT_OK(uv_thread_create(threads + 1, thread_run, &sem));
|
||||||
|
|
||||||
|
uv_sem_wait(&sem.worker);
|
||||||
|
|
||||||
|
r = uv_thread_getname(threads + 1, tn, sizeof(tn));
|
||||||
|
ASSERT_OK(r);
|
||||||
|
|
||||||
|
ASSERT_STR_EQ(tn, "worker-thread");
|
||||||
|
|
||||||
|
uv_sem_post(&sem.main);
|
||||||
|
|
||||||
|
ASSERT_OK(uv_thread_join(threads + 1));
|
||||||
|
|
||||||
|
uv_sem_destroy(&sem.main);
|
||||||
|
uv_sem_destroy(&sem.worker);
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
Loading…
Reference in New Issue
Block a user