diff options
author | David Turner <digit@android.com> | 2010-06-03 13:11:52 -0700 |
---|---|---|
committer | Android Code Review <code-review@android.com> | 2010-06-03 13:11:52 -0700 |
commit | f982f038329f7da7de5853c9d789ab138a4bcf16 (patch) | |
tree | 8f555e4c44b96d281460986a1d4c7c938523b22a /libc/bionic | |
parent | a910abcd194830d2d113b3e183eb7df4d36cd92e (diff) | |
parent | 78c1c04ced772298be8bdb5a94b6ce491bb9b3e1 (diff) | |
download | bionic-f982f038329f7da7de5853c9d789ab138a4bcf16.zip bionic-f982f038329f7da7de5853c9d789ab138a4bcf16.tar.gz bionic-f982f038329f7da7de5853c9d789ab138a4bcf16.tar.bz2 |
Merge "pthread: introduce pthread_setname_np() as a mean to give names to threads"
Diffstat (limited to 'libc/bionic')
-rw-r--r-- | libc/bionic/pthread.c | 54 |
1 files changed, 54 insertions, 0 deletions
diff --git a/libc/bionic/pthread.c b/libc/bionic/pthread.c index 7d4056d..666a6b8 100644 --- a/libc/bionic/pthread.c +++ b/libc/bionic/pthread.c @@ -43,6 +43,9 @@ #include <memory.h> #include <assert.h> #include <malloc.h> +#include <sys/prctl.h> +#include <sys/stat.h> +#include <fcntl.h> extern int __pthread_clone(int (*fn)(void*), void *child_stack, int flags, void *arg); extern void _exit_with_stack_teardown(void * stackBase, int stackSize, int retCode); @@ -1721,3 +1724,54 @@ int pthread_once( pthread_once_t* once_control, void (*init_routine)(void) ) } return 0; } + +/* This value is not exported by kernel headers, so hardcode it here */ +#define MAX_TASK_COMM_LEN 16 +#define TASK_COMM_FMT "/proc/self/task/%u/comm" + +int pthread_setname_np(pthread_t thid, const char *thname) +{ + size_t thname_len; + int saved_errno, ret; + + if (thid == 0 || thname == NULL) + return EINVAL; + + thname_len = strlen(thname); + if (thname_len >= MAX_TASK_COMM_LEN) + return ERANGE; + + saved_errno = errno; + if (thid == pthread_self()) + { + ret = prctl(PR_SET_NAME, (unsigned long)thname, 0, 0, 0) ? errno : 0; + } + else + { + /* Have to change another thread's name */ + pthread_internal_t *thread = (pthread_internal_t *)thid; + char comm_name[sizeof(TASK_COMM_FMT) + 8]; + ssize_t n; + int fd; + + snprintf(comm_name, sizeof(comm_name), TASK_COMM_FMT, (unsigned int)thread->kernel_id); + fd = open(comm_name, O_RDWR); + if (fd == -1) + { + ret = errno; + goto exit; + } + n = TEMP_FAILURE_RETRY(write(fd, thname, thname_len)); + close(fd); + + if (n < 0) + ret = errno; + else if ((size_t)n != thname_len) + ret = EIO; + else + ret = 0; + } +exit: + errno = saved_errno; + return ret; +} |