]> code.delx.au - pulseaudio/blobdiff - src/pulsecore/thread-posix.c
win32: Implement pa_random
[pulseaudio] / src / pulsecore / thread-posix.c
index 20ed16d95c9deb9472b28590d87592124002aab4..7d5252d686fee60b4aa9f95735efb751705c84a8 100644 (file)
@@ -6,7 +6,7 @@
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
 
   PulseAudio is free software; you can redistribute it and/or modify
   it under the terms of the GNU Lesser General Public License as published
-  by the Free Software Foundation; either version 2 of the License,
+  by the Free Software Foundation; either version 2.1 of the License,
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
   or (at your option) any later version.
 
   PulseAudio is distributed in the hope that it will be useful, but
 #include <sched.h>
 #include <errno.h>
 
 #include <sched.h>
 #include <errno.h>
 
+#ifdef __linux__
+#include <sys/prctl.h>
+#endif
+
 #include <pulse/xmalloc.h>
 #include <pulsecore/mutex.h>
 #include <pulsecore/once.h>
 #include <pulse/xmalloc.h>
 #include <pulsecore/mutex.h>
 #include <pulsecore/once.h>
@@ -41,6 +45,8 @@ struct pa_thread {
     pa_thread_func_t thread_func;
     void *userdata;
     pa_atomic_t running;
     pa_thread_func_t thread_func;
     void *userdata;
     pa_atomic_t running;
+    pa_bool_t joined;
+    char *name;
 };
 
 struct pa_tls {
 };
 
 struct pa_tls {
@@ -52,9 +58,11 @@ static void thread_free_cb(void *p) {
 
     pa_assert(t);
 
 
     pa_assert(t);
 
-    if (!t->thread_func)
+    if (!t->thread_func) {
         /* This is a foreign thread, we need to free the struct */
         /* This is a foreign thread, we need to free the struct */
+        pa_xfree(t->name);
         pa_xfree(t);
         pa_xfree(t);
+    }
 }
 
 PA_STATIC_TLS_DECLARE(current_thread, thread_free_cb);
 }
 
 PA_STATIC_TLS_DECLARE(current_thread, thread_free_cb);
@@ -63,6 +71,10 @@ static void* internal_thread_func(void *userdata) {
     pa_thread *t = userdata;
     pa_assert(t);
 
     pa_thread *t = userdata;
     pa_assert(t);
 
+#ifdef __linux__
+    prctl(PR_SET_NAME, t->name);
+#endif
+
     t->id = pthread_self();
 
     PA_STATIC_TLS_SET(current_thread, t);
     t->id = pthread_self();
 
     PA_STATIC_TLS_SET(current_thread, t);
@@ -74,15 +86,15 @@ static void* internal_thread_func(void *userdata) {
     return NULL;
 }
 
     return NULL;
 }
 
-pa_thread* pa_thread_new(pa_thread_func_t thread_func, void *userdata) {
+pa_thread* pa_thread_new(const char *name, pa_thread_func_t thread_func, void *userdata) {
     pa_thread *t;
 
     pa_assert(thread_func);
 
     pa_thread *t;
 
     pa_assert(thread_func);
 
-    t = pa_xnew(pa_thread, 1);
+    t = pa_xnew0(pa_thread, 1);
+    t->name = pa_xstrdup(name);
     t->thread_func = thread_func;
     t->userdata = userdata;
     t->thread_func = thread_func;
     t->userdata = userdata;
-    pa_atomic_store(&t->running, 0);
 
     if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) {
         pa_xfree(t);
 
     if (pthread_create(&t->id, NULL, internal_thread_func, t) < 0) {
         pa_xfree(t);
@@ -110,12 +122,19 @@ void pa_thread_free(pa_thread *t) {
     pa_assert(t);
 
     pa_thread_join(t);
     pa_assert(t);
 
     pa_thread_join(t);
+
+    pa_xfree(t->name);
     pa_xfree(t);
 }
 
 int pa_thread_join(pa_thread *t) {
     pa_assert(t);
     pa_xfree(t);
 }
 
 int pa_thread_join(pa_thread *t) {
     pa_assert(t);
+    pa_assert(t->thread_func);
+
+    if (t->joined)
+        return -1;
 
 
+    t->joined = TRUE;
     return pthread_join(t->id, NULL);
 }
 
     return pthread_join(t->id, NULL);
 }
 
@@ -128,10 +147,9 @@ pa_thread* pa_thread_self(void) {
     /* This is a foreign thread, let's create a pthread structure to
      * make sure that we can always return a sensible pointer */
 
     /* This is a foreign thread, let's create a pthread structure to
      * make sure that we can always return a sensible pointer */
 
-    t = pa_xnew(pa_thread, 1);
+    t = pa_xnew0(pa_thread, 1);
     t->id = pthread_self();
     t->id = pthread_self();
-    t->thread_func = NULL;
-    t->userdata = NULL;
+    t->joined = TRUE;
     pa_atomic_store(&t->running, 2);
 
     PA_STATIC_TLS_SET(current_thread, t);
     pa_atomic_store(&t->running, 2);
 
     PA_STATIC_TLS_SET(current_thread, t);
@@ -151,6 +169,36 @@ void pa_thread_set_data(pa_thread *t, void *userdata) {
     t->userdata = userdata;
 }
 
     t->userdata = userdata;
 }
 
+void pa_thread_set_name(pa_thread *t, const char *name) {
+    pa_assert(t);
+
+    pa_xfree(t->name);
+    t->name = pa_xstrdup(name);
+
+#ifdef __linux__
+    prctl(PR_SET_NAME, name);
+#endif
+}
+
+const char *pa_thread_get_name(pa_thread *t) {
+    pa_assert(t);
+
+#ifdef __linux__
+    if (!t->name) {
+        t->name = pa_xmalloc(17);
+
+        if (prctl(PR_GET_NAME, t->name) >= 0)
+            t->name[16] = 0;
+        else {
+            pa_xfree(t->name);
+            t->name = NULL;
+        }
+    }
+#endif
+
+    return t->name;
+}
+
 void pa_thread_yield(void) {
 #ifdef HAVE_PTHREAD_YIELD
     pthread_yield();
 void pa_thread_yield(void) {
 #ifdef HAVE_PTHREAD_YIELD
     pthread_yield();
@@ -192,4 +240,3 @@ void *pa_tls_set(pa_tls *t, void *userdata) {
     pa_assert_se(pthread_setspecific(t->key, userdata) == 0);
     return r;
 }
     pa_assert_se(pthread_setspecific(t->key, userdata) == 0);
     return r;
 }
-