summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPierre Ossman <ossman@cendio.se>2013-09-20 10:26:30 +0200
committerTanu Kaskinen <tanu.kaskinen@linux.intel.com>2014-06-06 15:33:58 +0300
commitfe346cadedd2a9b48fc36886c4a8d48f50302f07 (patch)
treefc145f12890d12c77640a1348d1e57994ba7b205
parent1a26dd3434d596cbf0f2f11bf2002bbc0cff5516 (diff)
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.
-rw-r--r--src/pulse/mainloop.c9
1 files changed, 2 insertions, 7 deletions
diff --git a/src/pulse/mainloop.c b/src/pulse/mainloop.c
index 66a147566..5ef58ffb3 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;
@@ -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)
/* 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) {
@@ -783,10 +780,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) {