aboutsummaryrefslogtreecommitdiffstats
path: root/src/PlayerThread.cxx
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2013-10-28 10:09:04 +0100
committerMax Kellermann <max@duempel.org>2013-10-28 10:22:05 +0100
commit1ad2475f9e3c88b992f3fd3d6a77842287d3e4db (patch)
treeb9d16a4bfeb2fa54f1bfe002df3da44341929709 /src/PlayerThread.cxx
parent5b5675cc121eff6ba4b89719a523bfbe3993ce2f (diff)
downloadmpd-1ad2475f9e3c88b992f3fd3d6a77842287d3e4db.tar.gz
mpd-1ad2475f9e3c88b992f3fd3d6a77842287d3e4db.tar.xz
mpd-1ad2475f9e3c88b992f3fd3d6a77842287d3e4db.zip
DecoderControl: convert mutex and client_cond to a reference
Share the Mutex between the DecoderThread and the PlayerThread. This simplifies synchronization between the two threads and fixes a freeze problem: while the PlayerThread waits for the DeocderThread, it cannot answer requests from the main thread, and the main thread will block until the DecoderThread finishes.
Diffstat (limited to 'src/PlayerThread.cxx')
-rw-r--r--src/PlayerThread.cxx31
1 files changed, 12 insertions, 19 deletions
diff --git a/src/PlayerThread.cxx b/src/PlayerThread.cxx
index 79bfc4018..7273a3300 100644
--- a/src/PlayerThread.cxx
+++ b/src/PlayerThread.cxx
@@ -322,9 +322,9 @@ Player::WaitForDecoder()
queued = false;
- Error error = dc.LockGetError();
+ pc.Lock();
+ Error error = dc.GetError();
if (error.IsDefined()) {
- pc.Lock();
pc.SetError(PlayerError::DECODER, std::move(error));
pc.next_song->Free();
@@ -347,8 +347,6 @@ Player::WaitForDecoder()
player_check_decoder_startup() */
decoder_starting = true;
- pc.Lock();
-
/* update PlayerControl's song information */
pc.total_time = pc.next_song->GetDuration();
pc.bit_rate = 0;
@@ -429,14 +427,11 @@ Player::CheckDecoderStartup()
{
assert(decoder_starting);
- dc.Lock();
+ pc.Lock();
Error error = dc.GetError();
if (error.IsDefined()) {
/* the decoder failed */
- dc.Unlock();
-
- pc.Lock();
pc.SetError(PlayerError::DECODER, std::move(error));
pc.Unlock();
@@ -444,7 +439,7 @@ Player::CheckDecoderStartup()
} else if (!dc.IsStarting()) {
/* the decoder is ready and ok */
- dc.Unlock();
+ pc.Unlock();
if (output_open &&
!audio_output_all_wait(pc, 1))
@@ -475,7 +470,7 @@ Player::CheckDecoderStartup()
/* the decoder is not yet ready; wait
some more */
dc.WaitForDecoder();
- dc.Unlock();
+ pc.Unlock();
return true;
}
@@ -807,19 +802,19 @@ Player::PlayNextChunk()
} else {
/* there are not enough decoded chunks yet */
- dc.Lock();
+ pc.Lock();
if (dc.IsIdle()) {
/* the decoder isn't running, abort
cross fading */
- dc.Unlock();
+ pc.Unlock();
xfade_state = CrossFadeState::DISABLED;
} else {
/* wait for the decoder */
dc.Signal();
dc.WaitForDecoder();
- dc.Unlock();
+ pc.Unlock();
return true;
}
@@ -865,12 +860,12 @@ Player::PlayNextChunk()
/* this formula should prevent that the decoder gets woken up
with each chunk; it is more efficient to make it decode a
larger block at a time */
- dc.Lock();
+ pc.Lock();
if (!dc.IsIdle() &&
dc.pipe->GetSize() <= (pc.buffered_before_play +
buffer.GetSize() * 3) / 4)
dc.Signal();
- dc.Unlock();
+ pc.Unlock();
return true;
}
@@ -957,11 +952,9 @@ Player::Run()
!SendSilence())
break;
- dc.Lock();
+ pc.Lock();
/* XXX race condition: check decoder again */
dc.WaitForDecoder();
- dc.Unlock();
- pc.Lock();
continue;
} else {
/* buffering is complete */
@@ -1107,7 +1100,7 @@ player_task(void *arg)
{
PlayerControl &pc = *(PlayerControl *)arg;
- DecoderControl dc;
+ DecoderControl dc(pc.mutex, pc.cond);
decoder_thread_start(dc);
MusicBuffer buffer(pc.buffer_chunks);