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.
This commit is contained in:
Pierre Ossman 2013-09-20 10:26:30 +02:00 committed by Tanu Kaskinen
parent 1a26dd3434
commit fe346caded

View file

@ -114,7 +114,6 @@ struct pa_mainloop {
int retval; int retval;
bool quit:1; bool quit:1;
pa_atomic_t wakeup_requested;
int wakeup_pipe[2]; int wakeup_pipe[2];
int wakeup_pipe_type; int wakeup_pipe_type;
@ -774,8 +773,6 @@ void pa_mainloop_wakeup(pa_mainloop *m) {
if (pa_write(m->wakeup_pipe[1], &c, sizeof(c), &m->wakeup_pipe_type) < 0) 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. */ /* 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_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) { static void clear_wakeup(pa_mainloop *m) {
@ -783,10 +780,8 @@ static void clear_wakeup(pa_mainloop *m) {
pa_assert(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) { int pa_mainloop_prepare(pa_mainloop *m, int timeout) {