Skip to content

Commit

Permalink
Change: Try stopping extmidi player with SIGINT first. (#11404)
Browse files Browse the repository at this point in the history
This may give the player a chance to issue MIDI note-off commands.

The kill/waitpid cycle is also less aggressive, waiting 50ms each time.
  • Loading branch information
PeterN committed Nov 27, 2023
1 parent a856fbe commit 4c6ccb5
Showing 1 changed file with 27 additions and 12 deletions.
39 changes: 27 additions & 12 deletions src/music/extmidi.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -130,23 +130,38 @@ void MusicDriver_ExtMidi::DoPlay()
}
}

void MusicDriver_ExtMidi::DoStop()
/**
* Try to end child process with kill/waitpid for up to 1 second.
* @param pid The process ID to end.
* @param signal The signal type to send.
* @return True if the process has been ended.
*/
static bool KillWait(pid_t &pid, int signal)
{
if (this->pid <= 0) return;

/* First try to gracefully stop for about five seconds;
* 5 seconds = 5000 milliseconds, 10 ms per cycle => 500 cycles. */
for (int i = 0; i < 500; i++) {
kill(this->pid, SIGTERM);
if (waitpid(this->pid, nullptr, WNOHANG) == this->pid) {
/* First try to stop for about a second;
* 1 seconds = 1000 milliseconds, 50 ms per cycle => 20 cycles. */
for (int i = 0; i < 20; i++) {
kill(pid, signal);
if (waitpid(pid, nullptr, WNOHANG) == pid) {
/* It has shut down, so we are done */
this->pid = -1;
return;
pid = -1;
return true;
}
/* Wait 10 milliseconds. */
CSleep(10);
/* Wait 50 milliseconds. */
CSleep(50);
}

return false;
}

void MusicDriver_ExtMidi::DoStop()
{
if (this->pid <= 0) return;

if (KillWait(this->pid, SIGINT)) return;

if (KillWait(this->pid, SIGTERM)) return;

Debug(driver, 0, "extmidi: gracefully stopping failed, trying the hard way");
/* Gracefully stopping failed. Do it the hard way
* and wait till the process finally died. */
Expand Down

0 comments on commit 4c6ccb5

Please sign in to comment.