[pulseaudio-commits] src/pulsecore

Tanu Kaskinen tanuk at kemper.freedesktop.org
Fri Nov 22 07:34:38 PST 2013


 src/pulsecore/lock-autospawn.c |    9 ++++++++-
 src/pulsecore/thread-posix.c   |    7 +++++++
 src/pulsecore/thread.h         |    1 +
 3 files changed, 16 insertions(+), 1 deletion(-)

New commits:
commit d8e2b3a78c6c60ffec9a115a0e35a3cb4c68598f
Author: Stefan Sperling <stsp at openbsd.org>
Date:   Thu Nov 21 18:47:42 2013 +0100

    Fix undefined behaviour in pulseaudio --start.
    
    Don't call pthread_join() to join a thread from a different
    process than the thread was created in. Doing so can lead to
    undefined behaviour.
    
    On OpenBSD, the symptom was a pulseaudio process with a single
    thread waiting forever for other threads to join. Since that
    process also held the autospawn lock, starting new pulseaudio
    processes with --start kept failing. The problem was analyzed
    with help from Philip Guenther.
    
    This patch adds a pa_thread_free_nojoin() function which can
    be used to free resources for a thread without a join, as
    suggested by Tanu Kaskinen.
    
    See https://bugs.freedesktop.org/show_bug.cgi?id=71738

diff --git a/src/pulsecore/lock-autospawn.c b/src/pulsecore/lock-autospawn.c
index 72806f8..82518db 100644
--- a/src/pulsecore/lock-autospawn.c
+++ b/src/pulsecore/lock-autospawn.c
@@ -114,8 +114,15 @@ static void unref(bool after_fork) {
     if (n_ref > 0)
         return;
 
+    /* Join threads only in the process the new thread was created in
+     * to avoid undefined behaviour.
+     * POSIX.1-2008 XSH 2.9.2 Thread IDs: "applications should only assume
+     * that thread IDs are usable and unique within a single process." */
     if (thread) {
-        pa_thread_free(thread);
+        if (after_fork)
+            pa_thread_free_nojoin(thread);
+	else
+            pa_thread_free(thread);
         thread = NULL;
     }
 
diff --git a/src/pulsecore/thread-posix.c b/src/pulsecore/thread-posix.c
index b422ab0..5c19b43 100644
--- a/src/pulsecore/thread-posix.c
+++ b/src/pulsecore/thread-posix.c
@@ -127,6 +127,13 @@ void pa_thread_free(pa_thread *t) {
     pa_xfree(t);
 }
 
+void pa_thread_free_nojoin(pa_thread *t) {
+    pa_assert(t);
+
+    pa_xfree(t->name);
+    pa_xfree(t);
+}
+
 int pa_thread_join(pa_thread *t) {
     pa_assert(t);
     pa_assert(t->thread_func);
diff --git a/src/pulsecore/thread.h b/src/pulsecore/thread.h
index 9cabb89..a6e5f42 100644
--- a/src/pulsecore/thread.h
+++ b/src/pulsecore/thread.h
@@ -39,6 +39,7 @@ typedef void (*pa_thread_func_t) (void *userdata);
 
 pa_thread* pa_thread_new(const char *name, pa_thread_func_t thread_func, void *userdata);
 void pa_thread_free(pa_thread *t);
+void pa_thread_free_nojoin(pa_thread *t);
 int pa_thread_join(pa_thread *t);
 int pa_thread_is_running(pa_thread *t);
 pa_thread *pa_thread_self(void);



More information about the pulseaudio-commits mailing list