From 58554e14f9995fdafe2338a69a42d9192b96f712 Mon Sep 17 00:00:00 2001 From: Max Kellermann Date: Fri, 26 Sep 2008 09:57:11 +0200 Subject: 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. --- src/decoder_thread.c | 2 -- src/main_notify.c | 2 -- src/notify.c | 20 ++++---------------- src/notify.h | 17 ----------------- src/output_thread.c | 2 -- src/player_thread.c | 2 -- 6 files changed, 4 insertions(+), 41 deletions(-) (limited to 'src') 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(¬ify->cond); } -void notify_enter(struct notify *notify) -{ - pthread_mutex_lock(¬ify->mutex); -} - -void notify_leave(struct notify *notify) -{ - pthread_mutex_unlock(¬ify->mutex); -} - void notify_wait(struct notify *notify) { + pthread_mutex_lock(¬ify->mutex); if (!notify->pending) pthread_cond_wait(¬ify->cond, ¬ify->mutex); + assert(notify->pending); notify->pending = 0; + pthread_mutex_unlock(¬ify->mutex); } void notify_signal(struct notify *notify) { + pthread_mutex_lock(¬ify->mutex); notify->pending = 1; pthread_cond_signal(¬ify->cond); -} - -void notify_signal_sync(struct notify *notify) -{ - pthread_mutex_lock(¬ify->mutex); - notify_signal(notify); pthread_mutex_unlock(¬ify->mutex); } diff --git a/src/notify.h b/src/notify.h index b9fd6e041..b8018232d 100644 --- a/src/notify.h +++ b/src/notify.h @@ -36,17 +36,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: -- cgit v1.2.3