From 68dd51f087a5ca70e44dd0558dad5fb935df3dc3 Mon Sep 17 00:00:00 2001 From: Pierre Ossman Date: Fri, 20 Sep 2013 10:26:30 +0200 Subject: [PATCH 5/8] mainloop: avoid race-y double wakeup status Having an extra variable that tracks the wakeup status introduces a race where the variable is set but the data has yet to propagate from the write end of the pipe to the read end. When this happens the system goes into a tight loop as select() always returns immediately. --- src/pulse/mainloop.c | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c index 60fbbb9..498ac7d 100644 --- a/src/pulse/mainloop.c +++ b/src/pulse/mainloop.c @@ -114,7 +114,6 @@ struct pa_mainloop { int retval; bool quit:1; - pa_atomic_t wakeup_requested; int wakeup_pipe[2]; int wakeup_pipe_type; @@ -772,8 +771,6 @@ void pa_mainloop_wakeup(pa_mainloop *m) { if (pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type) < 0) /* Not much options for recovering from the error. Let's at least log something. */ pa_log("pa_write() failed while trying to wake up the mainloop: %s", pa_cstrerror(errno)); - - pa_atomic_store(&m->wakeup_requested, true); } static void clear_wakeup(pa_mainloop *m) { @@ -781,10 +778,8 @@ static void clear_wakeup(pa_mainloop *m) { pa_assert(m); - if (pa_atomic_cmpxchg(&m->wakeup_requested, true, false)) { - while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c)) - ; - } + while (pa_read(m->wakeup_pipe[0], &c, sizeof(c), &m->wakeup_pipe_type) == sizeof(c)) + ; } int pa_mainloop_prepare(pa_mainloop *m, int timeout) { -- 1.8.3.1