output_thread: reimplement CANCEL synchronization

The output thread could hang indefinitely after finishing CANCEL,
because it could have missed the signal while the output was not
unlocked in ao_command_finished().

This patch removes the wait() call after CANCEL, and adds the flag
"allow_play" instead.  While this flag is set, playback is skipped.
With this flag, there will not be any excess wait() call after the
pipe has been cleared.

This patch fixes a bug that causes mpd to discontinue playback after
seeking, due to the race condition described above.
This commit is contained in:
Max Kellermann
2011-09-01 07:13:21 +02:00
parent 60f7ff3de5
commit 8b0b4ff086
7 changed files with 35 additions and 14 deletions

View File

@@ -648,12 +648,6 @@ static gpointer audio_output_task(gpointer arg)
}
ao_command_finished(ao);
/* the player thread will now clear our music
pipe - wait for a notify, to give it some
time */
if (ao->command == AO_COMMAND_NONE)
g_cond_wait(ao->cond, ao->mutex);
continue;
case AO_COMMAND_KILL:
@@ -663,7 +657,7 @@ static gpointer audio_output_task(gpointer arg)
return NULL;
}
if (ao->open && ao_play(ao))
if (ao->open && ao->allow_play && ao_play(ao))
/* don't wait for an event if there are more
chunks in the pipe */
continue;