Fixed a race condition in GaplessTransport where the recently created

player may get destroyed before the playback bootstrap finishes, leading
to a crash.

Also fixed a bug in LruDiskCache entry parsing that could result in
playback failing.
This commit is contained in:
casey langen 2020-10-10 22:05:30 -07:00
parent 346affb027
commit ccc4040213
2 changed files with 21 additions and 32 deletions

View File

@ -120,20 +120,20 @@ void GaplessTransport::StartWithPlayer(Player* newPlayer, StartMode mode) {
this->nextPlayer = nullptr;
this->activePlayer = newPlayer;
}
/* first argument suppresses the "Stop" event from getting triggered,
the second param is used for gapless playback -- we won't stop the output
and will allow pending buffers to finish if we're not automatically
playing the next track. note we do this outside of critical section so
outputs *can* stop buffers immediately, and not to worry about causing a
deadlock. */
this->StopInternal(true, !playingNext, newPlayer);
this->SetNextCanStart(false);
this->output->Resume();
/* first argument suppresses the "Stop" event from getting triggered,
the second param is used for gapless playback -- we won't stop the output
and will allow pending buffers to finish if we're not automatically
playing the next track. note we do this outside of critical section so
outputs *can* stop buffers immediately, and not to worry about causing a
deadlock. */
this->StopInternal(true, !playingNext, newPlayer);
this->SetNextCanStart(false);
this->output->Resume();
if (mode == StartMode::Immediate) {
newPlayer->Play();
if (mode == StartMode::Immediate) {
newPlayer->Play();
}
}
this->RaiseStreamEvent(StreamScheduled, newPlayer);

View File

@ -53,10 +53,9 @@ static std::string tempFilename(const std::string& root, size_t id) {
return root + "/" + PREFIX + "_" + std::to_string(id) + TEMP_EXTENSION;
}
static std::string finalFilename(const std::string& root, size_t id, std::string extension) {
al::replace_all(extension, "/", "-");
al::replace_all(extension, ".", "");
return root + "/" + PREFIX + "_" + std::to_string(id) + "." + extension;
static std::string finalFilename(const std::string& root, size_t id, std::string type) {
al::replace_all(type, "/", "-");
return root + "/" + PREFIX + "_" + std::to_string(id) + "_" + type;
}
static bool isTemp(const fs::path& path) {
@ -146,27 +145,17 @@ void LruDiskCache::Purge() {
}
LruDiskCache::EntryPtr LruDiskCache::Parse(const fs::path& path) {
std::string fn = path.stem().string(); /* no extension */
std::string ext = path.extension().string();
if (ext.size()) {
if (ext.at(0) == '.') {
ext = ext.substr(1);
}
al::replace_all(ext, "-", "/");
}
std::string fn = path.string();
std::vector<std::string> parts;
boost::split(parts, fn, boost::is_any_of("_"));
if (parts.size() == 2 && parts.at(0) == PREFIX) {
if (parts.size() == 3 && parts[0] == PREFIX) {
try {
auto entry = std::shared_ptr<Entry>(new Entry());
entry->id = std::stoull(parts.at(1).c_str());
entry->path = path.string();
entry->type = ext;
entry->id = std::stoull(parts[1].c_str());
entry->path = fn;
entry->type = parts[2];
entry->time = fs::last_write_time(path);
al::replace_all(entry->type, "-", "/");
return entry;
}
catch (...) {