aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--src/PlayerControl.cxx2
-rw-r--r--src/PlayerControl.hxx32
-rw-r--r--src/PlayerThread.cxx2
3 files changed, 34 insertions, 2 deletions
diff --git a/src/PlayerControl.cxx b/src/PlayerControl.cxx
index 3805f776f..01a9c7e81 100644
--- a/src/PlayerControl.cxx
+++ b/src/PlayerControl.cxx
@@ -60,7 +60,7 @@ static void
player_command_wait_locked(struct player_control *pc)
{
while (pc->command != PLAYER_COMMAND_NONE)
- pc->cond.wait(pc->mutex);
+ pc->ClientWait();
}
static void
diff --git a/src/PlayerControl.hxx b/src/PlayerControl.hxx
index 2b25177fb..de05e17ab 100644
--- a/src/PlayerControl.hxx
+++ b/src/PlayerControl.hxx
@@ -108,6 +108,13 @@ struct player_control {
*/
Cond cond;
+ /**
+ * This object gets signalled when the player thread has
+ * finished the #command. It wakes up the client that waits
+ * (i.e. the main thread).
+ */
+ Cond client_cond;
+
enum player_command command;
enum player_state state;
@@ -191,10 +198,35 @@ struct player_control {
* prior to calling this function.
*/
void Wait() {
+ assert(thread == g_thread_self());
+
cond.wait(mutex);
}
/**
+ * Wake up the client waiting for command completion.
+ *
+ * Caller must lock the object.
+ */
+ void ClientSignal() {
+ assert(thread == g_thread_self());
+
+ client_cond.signal();
+ }
+
+ /**
+ * The client calls this method to wait for command
+ * completion.
+ *
+ * Caller must lock the object.
+ */
+ void ClientWait() {
+ assert(thread != g_thread_self());
+
+ client_cond.wait(mutex);
+ }
+
+ /**
* @param song the song to be queued; the given instance will
* be owned and freed by the player
*/
diff --git a/src/PlayerThread.cxx b/src/PlayerThread.cxx
index 23487953f..ac2cb84bd 100644
--- a/src/PlayerThread.cxx
+++ b/src/PlayerThread.cxx
@@ -147,7 +147,7 @@ player_command_finished_locked(struct player_control *pc)
assert(pc->command != PLAYER_COMMAND_NONE);
pc->command = PLAYER_COMMAND_NONE;
- pc->cond.signal();
+ pc->ClientSignal();
}
static void