extmidi: Do not continuously retry if execvp fails

See: #478
This commit is contained in:
Jonathan G Rennison
2023-01-24 23:55:11 +00:00
parent 80f0250de6
commit 66166bad48
4 changed files with 21 additions and 3 deletions

View File

@@ -101,8 +101,10 @@ void MusicDriver_ExtMidi::StopSong()
bool MusicDriver_ExtMidi::IsSongPlaying() 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; this->pid = -1;
if (WIFEXITED(status) && WEXITSTATUS(status) == 255) this->failed = true;
} }
if (this->pid == -1 && this->song[0] != '\0') this->DoPlay(); if (this->pid == -1 && this->song[0] != '\0') this->DoPlay();
return this->pid != -1; return this->pid != -1;
@@ -115,6 +117,7 @@ void MusicDriver_ExtMidi::SetVolume(byte vol)
void MusicDriver_ExtMidi::DoPlay() void MusicDriver_ExtMidi::DoPlay()
{ {
this->failed = false;
this->pid = fork(); this->pid = fork();
switch (this->pid) { switch (this->pid) {
case 0: { case 0: {
@@ -123,7 +126,7 @@ void MusicDriver_ExtMidi::DoPlay()
if (d != -1 && dup2(d, 1) != -1 && dup2(d, 2) != -1) { if (d != -1 && dup2(d, 1) != -1 && dup2(d, 2) != -1) {
execvp(this->params[0], this->params); execvp(this->params[0], this->params);
} }
_exit(1); _exit(255);
} }
case -1: case -1:

View File

@@ -17,6 +17,7 @@ private:
char **params; char **params;
char song[MAX_PATH]; char song[MAX_PATH];
pid_t pid; pid_t pid;
bool failed = false;
void DoPlay(); void DoPlay();
void DoStop(); void DoStop();
@@ -34,6 +35,8 @@ public:
void SetVolume(byte vol) override; void SetVolume(byte vol) override;
const char *GetName() const override { return "extmidi"; } const char *GetName() const override { return "extmidi"; }
bool IsInFailedState() override { return this->failed; }
}; };
class FMusicDriver_ExtMidi : public DriverFactoryBase { class FMusicDriver_ExtMidi : public DriverFactoryBase {

View File

@@ -40,6 +40,12 @@ public:
*/ */
virtual void SetVolume(byte vol) = 0; 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. * Get the currently active instance of the music driver.
*/ */

View File

@@ -262,7 +262,13 @@ void MusicSystem::CheckStatus()
} }
if (this->active_playlist.empty()) return; if (this->active_playlist.empty()) return;
/* If we were supposed to be playing, but music has stopped, move to next song */ /* 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? */ /** Is the player getting music right now? */