decoder/Control: work around crash after SEEK was too late

See code comment.

Closes https://github.com/MusicPlayerDaemon/MPD/issues/629
This commit is contained in:
Max Kellermann 2019-08-20 20:01:53 +02:00
parent f3d16f6d1b
commit ca450663d0
2 changed files with 14 additions and 0 deletions

2
NEWS
View File

@ -3,6 +3,8 @@ ver 0.21.14 (not yet released)
- sidplay: show track durations in database - sidplay: show track durations in database
- sidplay: convert tag values from Windows-1252 charset - sidplay: convert tag values from Windows-1252 charset
- sidplay: strip text from "Date" tag - sidplay: strip text from "Date" tag
* player
- fix crash after song change
ver 0.21.13 (2019/08/06) ver 0.21.13 (2019/08/06)
* input * input

View File

@ -147,6 +147,18 @@ DecoderControl::Seek(SongTime t)
seek_error = false; seek_error = false;
SynchronousCommandLocked(DecoderCommand::SEEK); SynchronousCommandLocked(DecoderCommand::SEEK);
while (state == DecoderState::START)
/* If the decoder falls back to DecoderState::START,
this means that our SEEK command arrived too late,
and the decoder had meanwhile finished decoding and
went idle. Our SEEK command is finished, but that
means only that the decoder thread has launched the
decoder. To work around illegal states, we wait
until the decoder plugin has become ready. This is
a kludge, built on top of the "late seek" kludge.
Not exactly elegant, sorry. */
WaitForDecoder();
if (seek_error) if (seek_error)
throw std::runtime_error("Decoder failed to seek"); throw std::runtime_error("Decoder failed to seek");
} }