aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2008-09-26 09:57:11 +0200
committerMax Kellermann <max@duempel.org>2008-09-26 09:57:11 +0200
commit58554e14f9995fdafe2338a69a42d9192b96f712 (patch)
tree83881d1e2131795581c822aa5cd01ddce42cf80f
parent323e86489fb9544b3a2faa9e9004ac0b72bf01ca (diff)
downloadmpd-58554e14f9995fdafe2338a69a42d9192b96f712.tar.gz
mpd-58554e14f9995fdafe2338a69a42d9192b96f712.tar.xz
mpd-58554e14f9995fdafe2338a69a42d9192b96f712.zip
notify: protect notify->pending with the mutex
There was a known deadlocking bug in the notify library: when the other thread set notify->pending after the according check in notify_wait(), the latter thread was deadlocked. Resolve this by synchronizing all accesses to notify->pending with the notify object's mutex. Since notify_signal_sync() was never used, we can remove it. As a consequence, we don't need notify_enter() and notify_leave() anymore; eliminate them, too.
-rw-r--r--src/decoder_thread.c2
-rw-r--r--src/main_notify.c2
-rw-r--r--src/notify.c20
-rw-r--r--src/notify.h17
-rw-r--r--src/output_thread.c2
-rw-r--r--src/player_thread.c2
6 files changed, 4 insertions, 41 deletions
diff --git a/src/decoder_thread.c b/src/decoder_thread.c
index 60381b1f6..0b2a6dc2d 100644
--- a/src/decoder_thread.c
+++ b/src/decoder_thread.c
@@ -167,8 +167,6 @@ stop_no_close:
static void * decoder_task(mpd_unused void *arg)
{
- notify_enter(&dc.notify);
-
while (1) {
assert(dc.state == DECODE_STATE_STOP);
diff --git a/src/main_notify.c b/src/main_notify.c
index 4e5b786a2..96fb374b5 100644
--- a/src/main_notify.c
+++ b/src/main_notify.c
@@ -115,8 +115,6 @@ void wait_main_task(void)
{
assert(pthread_equal(main_task, pthread_self()));
- notify_enter(&main_notify);
notify_wait(&main_notify);
- notify_leave(&main_notify);
}
diff --git a/src/notify.c b/src/notify.c
index edb77f66d..5aaecd0ad 100644
--- a/src/notify.c
+++ b/src/notify.c
@@ -40,32 +40,20 @@ void notify_deinit(struct notify *notify)
pthread_cond_destroy(&notify->cond);
}
-void notify_enter(struct notify *notify)
-{
- pthread_mutex_lock(&notify->mutex);
-}
-
-void notify_leave(struct notify *notify)
-{
- pthread_mutex_unlock(&notify->mutex);
-}
-
void notify_wait(struct notify *notify)
{
+ pthread_mutex_lock(&notify->mutex);
if (!notify->pending)
pthread_cond_wait(&notify->cond, &notify->mutex);
+ assert(notify->pending);
notify->pending = 0;
+ pthread_mutex_unlock(&notify->mutex);
}
void notify_signal(struct notify *notify)
{
+ pthread_mutex_lock(&notify->mutex);
notify->pending = 1;
pthread_cond_signal(&notify->cond);
-}
-
-void notify_signal_sync(struct notify *notify)
-{
- pthread_mutex_lock(&notify->mutex);
- notify_signal(notify);
pthread_mutex_unlock(&notify->mutex);
}
diff --git a/src/notify.h b/src/notify.h
index b9fd6e041..b8018232d 100644
--- a/src/notify.h
+++ b/src/notify.h
@@ -37,17 +37,6 @@ void notify_init(struct notify *notify);
void notify_deinit(struct notify *notify);
/**
- * The thread which shall be notified by this object must call this
- * function before any notify_wait() invocation. It locks the mutex.
- */
-void notify_enter(struct notify *notify);
-
-/**
- * Neutralize notify_leave().
- */
-void notify_leave(struct notify *notify);
-
-/**
* Wait for a notification. Return immediately if we have already
* been notified since we last returned from notify_wait().
*/
@@ -58,10 +47,4 @@ void notify_wait(struct notify *notify);
*/
void notify_signal(struct notify *notify);
-/**
- * Notify the thread synchonously, i.e. wait until it has received the
- * notification.
- */
-void notify_signal_sync(struct notify *notify);
-
#endif
diff --git a/src/output_thread.c b/src/output_thread.c
index a92f0bafd..4bc5d8fcb 100644
--- a/src/output_thread.c
+++ b/src/output_thread.c
@@ -67,8 +67,6 @@ static void *audio_output_task(void *arg)
{
struct audio_output *ao = arg;
- notify_enter(&ao->notify);
-
while (1) {
switch (ao->command) {
case AO_COMMAND_NONE:
diff --git a/src/player_thread.c b/src/player_thread.c
index cf5e71f61..171bd71c4 100644
--- a/src/player_thread.c
+++ b/src/player_thread.c
@@ -384,8 +384,6 @@ static void do_play(void)
static void * player_task(mpd_unused void *arg)
{
- notify_enter(&pc.notify);
-
while (1) {
switch (pc.command) {
case PLAYER_COMMAND_PLAY: