aboutsummaryrefslogtreecommitdiffstats
path: root/src/player_thread.c
diff options
context:
space:
mode:
authorMax Kellermann <max@duempel.org>2009-08-13 23:33:46 +0200
committerMax Kellermann <max@duempel.org>2009-08-13 23:33:46 +0200
commite28a0e97b5d2e54684c6452d6d45f64ff1e542d9 (patch)
tree38f0c66be040d13c8356293e64cedf8280174fbc /src/player_thread.c
parent499ed62dd790949c571517b54ef0e96fad26b16b (diff)
downloadmpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.tar.gz
mpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.tar.xz
mpd-e28a0e97b5d2e54684c6452d6d45f64ff1e542d9.zip
decoder_control: protect command, state with a mutex
Replace decoder_control.notify with decoder_control.mutex and decoder_control.cond. Lock the mutex on all accesses to decoder_control.command and decoder_control.state.
Diffstat (limited to 'src/player_thread.c')
-rw-r--r--src/player_thread.c30
1 files changed, 23 insertions, 7 deletions
diff --git a/src/player_thread.c b/src/player_thread.c
index f23faa8b3..b501937b6 100644
--- a/src/player_thread.c
+++ b/src/player_thread.c
@@ -135,7 +135,7 @@ player_wait_for_decoder(struct player *player)
{
dc_command_wait(&pc.notify);
- if (decoder_has_failed()) {
+ if (decoder_lock_has_failed()) {
assert(dc.next_song == NULL || dc.next_song->url != NULL);
pc.errored_song = dc.next_song;
pc.error = PLAYER_ERROR_FILE;
@@ -174,10 +174,14 @@ player_check_decoder_startup(struct player *player)
{
assert(player->decoder_starting);
+ decoder_lock();
+
if (decoder_has_failed()) {
/* the decoder failed */
assert(dc.next_song == NULL || dc.next_song->url != NULL);
+ decoder_unlock();
+
pc.errored_song = dc.next_song;
pc.error = PLAYER_ERROR_FILE;
@@ -185,6 +189,8 @@ player_check_decoder_startup(struct player *player)
} else if (!decoder_is_starting()) {
/* the decoder is ready and ok */
+ decoder_unlock();
+
if (audio_format_defined(&player->play_audio_format) &&
!audio_output_all_wait(1))
/* the output devices havn't finished playing
@@ -219,6 +225,7 @@ player_check_decoder_startup(struct player *player)
} else {
/* the decoder is not yet ready; wait
some more */
+ decoder_unlock();
notify_wait(&pc.notify);
return true;
@@ -512,13 +519,20 @@ play_next_chunk(struct player *player)
music_buffer_return(player_buffer, other_chunk);
} else {
/* there are not enough decoded chunks yet */
+
+ decoder_lock();
+
if (decoder_is_idle()) {
/* the decoder isn't running, abort
cross fading */
+ decoder_unlock();
+
player->xfade = XFADE_DISABLED;
} else {
/* wait for the decoder */
- notify_signal(&dc.notify);
+ decoder_signal();
+ decoder_unlock();
+
notify_wait(&pc.notify);
return true;
@@ -549,10 +563,12 @@ play_next_chunk(struct player *player)
/* 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 */
+ decoder_lock();
if (!decoder_is_idle() &&
music_pipe_size(dc.pipe) <= (pc.buffered_before_play +
music_buffer_size(player_buffer) * 3) / 4)
- notify_signal(&dc.notify);
+ decoder_signal();
+ decoder_unlock();
return true;
}
@@ -634,7 +650,7 @@ static void do_play(void)
prevent stuttering on slow machines */
if (music_pipe_size(player.pipe) < pc.buffered_before_play &&
- !decoder_is_idle()) {
+ !decoder_lock_is_idle()) {
/* not enough decoded buffer space yet */
if (!player.paused &&
@@ -669,7 +685,7 @@ static void do_play(void)
*/
#endif
- if (decoder_is_idle() && player.queued) {
+ if (decoder_lock_is_idle() && player.queued) {
/* the decoder has finished the current song;
make it decode the next song */
assert(pc.next_song != NULL);
@@ -682,7 +698,7 @@ static void do_play(void)
if (dc.pipe != NULL && dc.pipe != player.pipe &&
player.xfade == XFADE_UNKNOWN &&
- !decoder_is_starting()) {
+ !decoder_lock_is_starting()) {
/* enable cross fading in this song? if yes,
calculate how many chunks will be required
for it */
@@ -720,7 +736,7 @@ static void do_play(void)
if (!player_song_border(&player))
break;
- } else if (decoder_is_idle()) {
+ } else if (decoder_lock_is_idle()) {
/* check the size of the pipe again, because
the decoder thread may have added something
since we last checked */