From 66166bad48d22f160764fd951a931bd1b80788d1 Mon Sep 17 00:00:00 2001 From: Jonathan G Rennison Date: Tue, 24 Jan 2023 23:55:11 +0000 Subject: [PATCH] extmidi: Do not continuously retry if execvp fails See: #478 --- src/music/extmidi.cpp | 7 +++++-- src/music/extmidi.h | 3 +++ src/music/music_driver.hpp | 6 ++++++ src/music_gui.cpp | 8 +++++++- 4 files changed, 21 insertions(+), 3 deletions(-) diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp index f882452501..2c3aab3dfe 100644 --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.cpp @@ -101,8 +101,10 @@ void MusicDriver_ExtMidi::StopSong() bool MusicDriver_ExtMidi::IsSongPlaying() { - if (this->pid != -1 && waitpid(this->pid, nullptr, WNOHANG) == this->pid) { + int status = 0; + if (this->pid != -1 && waitpid(this->pid, &status, WNOHANG) == this->pid) { this->pid = -1; + if (WIFEXITED(status) && WEXITSTATUS(status) == 255) this->failed = true; } if (this->pid == -1 && this->song[0] != '\0') this->DoPlay(); return this->pid != -1; @@ -115,6 +117,7 @@ void MusicDriver_ExtMidi::SetVolume(byte vol) void MusicDriver_ExtMidi::DoPlay() { + this->failed = false; this->pid = fork(); switch (this->pid) { case 0: { @@ -123,7 +126,7 @@ void MusicDriver_ExtMidi::DoPlay() if (d != -1 && dup2(d, 1) != -1 && dup2(d, 2) != -1) { execvp(this->params[0], this->params); } - _exit(1); + _exit(255); } case -1: diff --git a/src/music/extmidi.h b/src/music/extmidi.h index f43bbad179..783c7fbd77 100644 --- a/src/music/extmidi.h +++ b/src/music/extmidi.h @@ -17,6 +17,7 @@ private: char **params; char song[MAX_PATH]; pid_t pid; + bool failed = false; void DoPlay(); void DoStop(); @@ -34,6 +35,8 @@ public: void SetVolume(byte vol) override; const char *GetName() const override { return "extmidi"; } + + bool IsInFailedState() override { return this->failed; } }; class FMusicDriver_ExtMidi : public DriverFactoryBase { diff --git a/src/music/music_driver.hpp b/src/music/music_driver.hpp index 3953685bf0..b5984a4d82 100644 --- a/src/music/music_driver.hpp +++ b/src/music/music_driver.hpp @@ -40,6 +40,12 @@ public: */ virtual void SetVolume(byte vol) = 0; + /** + * Is playback in a failed state? + * @return True if playback is in a failed state. + */ + virtual bool IsInFailedState() { return false; } + /** * Get the currently active instance of the music driver. */ diff --git a/src/music_gui.cpp b/src/music_gui.cpp index a2bd44add7..720ed96a03 100644 --- a/src/music_gui.cpp +++ b/src/music_gui.cpp @@ -262,7 +262,13 @@ void MusicSystem::CheckStatus() } if (this->active_playlist.empty()) return; /* If we were supposed to be playing, but music has stopped, move to next song */ - if (this->IsPlaying() && !MusicDriver::GetInstance()->IsSongPlaying()) this->Next(); + if (this->IsPlaying() && !MusicDriver::GetInstance()->IsSongPlaying()) { + if (MusicDriver::GetInstance()->IsInFailedState()) { + this->Stop(); + } else { + this->Next(); + } + } } /** Is the player getting music right now? */