aboutsummaryrefslogtreecommitdiffstats
path: root/src/player_control.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-10-31 17:02:12 +0100
committerMax Kellermann <max@duempel.org>2009-10-31 17:02:12 +0100
commit25a806a347ce420126eb75d82c5fb875eb0a5e0d (patch)
tree0d39bed8c073a720acd42f17b04dbee91b0a8c01 /src/player_control.c
parent73cff374fd94a1c16e0201fcda020396c0f41962 (diff)
downloadmpd-25a806a347ce420126eb75d82c5fb875eb0a5e0d.tar.gz
mpd-25a806a347ce420126eb75d82c5fb875eb0a5e0d.tar.xz
mpd-25a806a347ce420126eb75d82c5fb875eb0a5e0d.zip
player_control: protect command, state, error with a mutex
Use GMutex/GCond instead of the notify library. Manually lock the player_control object before accessing the protected attributes. Use the GCond object to notify the player thread and the main thread.
Diffstat (limited to 'src/player_control.c')
-rw-r--r--src/player_control.c42
1 files changed, 35 insertions, 7 deletions
diff --git a/src/player_control.c b/src/player_control.c
index 23ae136ac..aa018ceda 100644
--- a/src/player_control.c
+++ b/src/player_control.c
@@ -18,6 +18,7 @@
*/
#include "player_control.h"
+#include "decoder_control.h"
#include "path.h"
#include "log.h"
#include "tag.h"
@@ -35,7 +36,10 @@ void pc_init(unsigned buffer_chunks, unsigned int buffered_before_play)
{
pc.buffer_chunks = buffer_chunks;
pc.buffered_before_play = buffered_before_play;
- notify_init(&pc.notify);
+
+ pc.mutex = g_mutex_new();
+ pc.cond = g_cond_new();
+
pc.command = PLAYER_COMMAND_NONE;
pc.error = PLAYER_ERROR_NOERROR;
pc.state = PLAYER_STATE_STOP;
@@ -44,7 +48,16 @@ void pc_init(unsigned buffer_chunks, unsigned int buffered_before_play)
void pc_deinit(void)
{
- notify_deinit(&pc.notify);
+ g_cond_free(pc.cond);
+ g_mutex_free(pc.mutex);
+}
+
+void
+player_wait_decoder(void)
+{
+ /* during this function, the decoder lock is held, because
+ we're waiting for the decoder thread */
+ g_cond_wait(pc.cond, dc.mutex);
}
void
@@ -56,15 +69,30 @@ pc_song_deleted(const struct song *song)
}
}
-static void player_command(enum player_command cmd)
+static void
+player_command_wait_locked(void)
+{
+ while (pc.command != PLAYER_COMMAND_NONE) {
+ player_signal();
+ g_cond_wait(main_cond, pc.mutex);
+ }
+}
+
+static void
+player_command_locked(enum player_command cmd)
{
assert(pc.command == PLAYER_COMMAND_NONE);
pc.command = cmd;
- while (pc.command != PLAYER_COMMAND_NONE) {
- notify_signal(&pc.notify);
- notify_wait(&main_notify);
- }
+ player_command_wait_locked();
+}
+
+static void
+player_command(enum player_command cmd)
+{
+ player_lock();
+ player_command_locked(cmd);
+ player_unlock();
}
void