summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIvan Zhakov <ivan@apache.org>2022-06-27 23:13:52 +0000
committerIvan Zhakov <ivan@apache.org>2022-06-27 23:13:52 +0000
commit7791a5b5497b7dad6f500e2db2df4da1d35cacaf (patch)
tree068fa7aef0a464175de8bfbb102f046b8ec5f5c3
parent7bcf46ab762c90550e499ae1a5a4134ea3d27a8c (diff)
downloadapr-7791a5b5497b7dad6f500e2db2df4da1d35cacaf.tar.gz
On 'thread-name' branch: Add apr_thread_name_get() and apr_thread_name_set()
API to get/set thread name. git-svn-id: https://svn.apache.org/repos/asf/apr/apr/branches/thread-name@1902297 13f79535-47bb-0310-9956-ffa450edef68
-rw-r--r--include/apr_thread_proc.h23
-rw-r--r--include/arch/win32/apr_arch_misc.h10
-rw-r--r--test/testthread.c31
-rw-r--r--threadproc/beos/thread.c14
-rw-r--r--threadproc/netware/thread.c12
-rw-r--r--threadproc/os2/thread.c14
-rw-r--r--threadproc/unix/thread.c47
-rw-r--r--threadproc/win32/thread.c72
8 files changed, 223 insertions, 0 deletions
diff --git a/include/apr_thread_proc.h b/include/apr_thread_proc.h
index 952c76d2d..39dc25811 100644
--- a/include/apr_thread_proc.h
+++ b/include/apr_thread_proc.h
@@ -331,6 +331,29 @@ APR_DECLARE(apr_status_t) apr_thread_join(apr_status_t *retval,
apr_thread_t *thd);
/**
+ * Get name of thread
+ * @param name The variable where is will be stored name of thread.
+ * @param thread The thread that name required to get.
+ * Current thread will be used if @param thread is NULL.
+ * @param cont The pool to use
+ */
+APR_DECLARE(apr_status_t) apr_thread_name_get(char **name,
+ apr_thread_t *thread,
+ apr_pool_t *pool);
+
+/**
+ * Set name of thread
+ * @param name The name of thread must be setted. If name is to long, then
+ * name stripped to max length supported by operation system.
+ * @param thread The thread that name will be changed.
+ * Current thread will be used if @param thread is NULL.
+ * @param cont The pool to use for temporary allocations
+ */
+APR_DECLARE(apr_status_t) apr_thread_name_set(const char *name,
+ apr_thread_t *thread,
+ apr_pool_t *pool);
+
+/**
* force the current thread to yield the processor
*/
APR_DECLARE(void) apr_thread_yield(void);
diff --git a/include/arch/win32/apr_arch_misc.h b/include/arch/win32/apr_arch_misc.h
index 057f4adfa..53ef2ea1b 100644
--- a/include/arch/win32/apr_arch_misc.h
+++ b/include/arch/win32/apr_arch_misc.h
@@ -289,4 +289,14 @@ APR_DECLARE_LATE_DLL_FUNC(DLL_API_MS_WIN_DOWNLEVEL_SHELL32_L1_1_0, LPWSTR *,
(LPCWSTR lpCmdLine, int *pNumArgs),
(lpCmdLine, pNumArgs));
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, GetThreadDescription, 0, (
+ HANDLE hThread,
+ PWSTR *ppszThreadDescription),
+ (hThread, ppszThreadDescription));
+
+APR_DECLARE_LATE_DLL_FUNC(DLL_WINBASEAPI, BOOL, WINAPI, SetThreadDescription, 0, (
+ HANDLE hThread,
+ PCWSTR lpThreadDescription),
+ (hThread, lpThreadDescription));
+
#endif /* ! MISC_H */
diff --git a/test/testthread.c b/test/testthread.c
index e64bdd4b7..2f8b1cb5a 100644
--- a/test/testthread.c
+++ b/test/testthread.c
@@ -107,6 +107,36 @@ static void check_thread_once(abts_case *tc, void *data)
ABTS_INT_EQUAL(tc, 1, value);
}
+static void thread_name(abts_case *tc, void *data)
+{
+ apr_status_t rv;
+ char *name;
+
+ rv = apr_thread_name_set("thread-1", NULL, p);
+ if (rv == APR_ENOTIMPL) {
+ ABTS_NOT_IMPL(tc, "apr_thread_name_set is not implemented.")
+ return ;
+ }
+
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+ rv = apr_thread_name_get(&name, NULL, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+ ABTS_STR_EQUAL(tc, "thread-1", name);
+
+ rv = apr_thread_name_set("thread-1", NULL, p);
+ if (rv == APR_ENOTIMPL) {
+ ABTS_NOT_IMPL(tc, "apr_thread_name_set is not implemented.")
+ return ;
+ }
+
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+
+ rv = apr_thread_name_get(&name, NULL, p);
+ ABTS_INT_EQUAL(tc, APR_SUCCESS, rv);
+ ABTS_STR_EQUAL(tc, "thread-1", name);
+}
+
#else
static void threads_not_impl(abts_case *tc, void *data)
@@ -128,6 +158,7 @@ abts_suite *testthread(abts_suite *suite)
abts_run_test(suite, join_threads, NULL);
abts_run_test(suite, check_locks, NULL);
abts_run_test(suite, check_thread_once, NULL);
+ abts_run_test(suite, thread_name, NULL);
#endif
return suite;
diff --git a/threadproc/beos/thread.c b/threadproc/beos/thread.c
index f5752a81e..968031562 100644
--- a/threadproc/beos/thread.c
+++ b/threadproc/beos/thread.c
@@ -343,3 +343,17 @@ APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
}
APR_POOL_IMPLEMENT_ACCESSOR(thread)
+
+APR_DECLARE(apr_status_t) apr_thread_name_set(const char* name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_thread_name_get(apr_thread_t *thread,
+ char **name,
+ apr_pool_t pool)
+{
+ return APR_ENOTIMPL;
+}
diff --git a/threadproc/netware/thread.c b/threadproc/netware/thread.c
index 24122119a..404b42f74 100644
--- a/threadproc/netware/thread.c
+++ b/threadproc/netware/thread.c
@@ -354,4 +354,16 @@ APR_DECLARE(apr_status_t) apr_thread_once(apr_thread_once_t *control,
APR_POOL_IMPLEMENT_ACCESSOR(thread)
+APR_DECLARE(apr_status_t) apr_thread_name_set(const char *name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+APR_DECLARE(apr_status_t) apr_thread_name_get(char ** name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+} \ No newline at end of file
diff --git a/threadproc/os2/thread.c b/threadproc/os2/thread.c
index e0540188d..9b4eb340a 100644
--- a/threadproc/os2/thread.c
+++ b/threadproc/os2/thread.c
@@ -259,6 +259,20 @@ APR_DECLARE(apr_status_t) apr_thread_detach(apr_thread_t *thd)
return APR_SUCCESS;
}
+APR_DECLARE(apr_status_t) apr_thread_name_set(const char *name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
+APR_DECLARE(apr_status_t) apr_thread_name_get(char ** name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ return APR_ENOTIMPL;
+}
+
void apr_thread_yield()
diff --git a/threadproc/unix/thread.c b/threadproc/unix/thread.c
index 209fe7c86..e88592201 100644
--- a/threadproc/unix/thread.c
+++ b/threadproc/unix/thread.c
@@ -22,6 +22,11 @@
#if APR_HAVE_PTHREAD_H
+/* Unfortunately the kernel headers do not export the TASK_COMM_LEN
+ macro. So we have to define it here. Used in apr_thread_name_get and
+ apr_thread_name_set functions */
+#define TASK_COMM_LEN 16
+
/* Destroy the threadattr object */
static apr_status_t threadattr_cleanup(void *data)
{
@@ -277,6 +282,48 @@ APR_DECLARE(apr_thread_t *) apr_thread_current(void)
#endif
}
+APR_DECLARE(apr_status_t) apr_thread_name_set(const char *name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ pthread_t td;
+
+ size_t name_len;
+ if (!name) {
+ return APR_BADARG;
+ }
+
+ if (thread) {
+ td = *thread->td;
+ }
+ else {
+ td = pthread_self();
+ }
+
+ name_len = strlen(name);
+ if (name_len >= TASK_COMM_LEN) {
+ name = name + name_len - TASK_COMM_LEN + 1;
+ }
+
+ return pthread_setname_np(td, name);
+}
+
+APR_DECLARE(apr_status_t) apr_thread_name_get(char **name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ pthread_t td;
+ if (thread) {
+ td = *thread->td;
+ }
+ else {
+ td = pthread_self();
+ }
+
+ *name = apr_pcalloc(pool, TASK_COMM_LEN);
+ return pthread_getname_np(td, *name, TASK_COMM_LEN);
+}
+
APR_DECLARE(apr_os_thread_t) apr_os_thread_current(void)
{
return pthread_self();
diff --git a/threadproc/win32/thread.c b/threadproc/win32/thread.c
index 0b672e698..90ee9f1cb 100644
--- a/threadproc/win32/thread.c
+++ b/threadproc/win32/thread.c
@@ -24,6 +24,7 @@
#include <process.h>
#endif
#include "apr_arch_misc.h"
+#include "apr_arch_utf8.h"
/* Chosen for us by apr_initialize */
DWORD tls_apr_thread = 0;
@@ -301,6 +302,77 @@ APR_DECLARE(apr_status_t) apr_thread_data_set(void *data, const char *key,
return apr_pool_userdata_set(data, key, cleanup, thread->pool);
}
+APR_DECLARE(apr_status_t) apr_thread_name_set(const char *name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ apr_wchar_t *wname;
+ apr_size_t wname_len;
+ apr_size_t name_len;
+ apr_status_t rv;
+ HANDLE thread_handle;
+
+ if (!APR_HAVE_LATE_DLL_FUNC(SetThreadDescription)) {
+ return APR_ENOTIMPL;
+ }
+
+ if (thread) {
+ thread_handle = thread->td;
+ }
+ else {
+ thread_handle = GetCurrentThread();
+ }
+
+ name_len = strlen(name) + 1;
+ wname_len = name_len;
+ wname = apr_palloc(pool, wname_len * sizeof(apr_wchar_t));
+ rv = apr_conv_utf8_to_ucs2(name, &name_len, wname, &wname_len);
+ if (rv) {
+ return rv;
+ }
+
+ if (!apr_winapi_SetThreadDescription(thread_handle, wname)) {
+ return apr_get_os_error();
+ }
+
+ return APR_SUCCESS;
+}
+
+APR_DECLARE(apr_status_t) apr_thread_name_get(char **name,
+ apr_thread_t *thread,
+ apr_pool_t *pool)
+{
+ apr_wchar_t *wname;
+ apr_size_t wname_len;
+ apr_size_t name_len;
+ apr_status_t rv;
+ HANDLE thread_handle;
+
+ if (!APR_HAVE_LATE_DLL_FUNC(GetThreadDescription)) {
+ return APR_ENOTIMPL;
+ }
+
+ if (thread) {
+ thread_handle = thread->td;
+ }
+ else {
+ thread_handle = GetCurrentThread();
+ }
+
+ if (!apr_winapi_GetThreadDescription(thread_handle, &wname)) {
+ return apr_get_os_error();
+ }
+
+ wname_len = wcslen(wname) + 1;
+
+ name_len = wname_len * 3;
+ *name = apr_palloc(pool, name_len);
+
+ rv = apr_conv_ucs2_to_utf8(wname, &wname_len, *name, &name_len);
+ LocalFree(wname);
+
+ return rv;
+}
APR_DECLARE(apr_os_thread_t) apr_os_thread_current(void)
{