From 4c6ccb524827ffd25a01f1f530fcadfb4b548eac Mon Sep 17 00:00:00 2001 From: Peter Nelson Date: Mon, 27 Nov 2023 20:39:22 +0000 Subject: [PATCH] Change: Try stopping extmidi player with SIGINT first. (#11404) 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. --- src/music/extmidi.cpp | 39 +++++++++++++++++++++++++++------------ 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp index 86b8bb57c0..74539ff569 100644 --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.cpp @@ -130,22 +130,37 @@ void MusicDriver_ExtMidi::DoPlay() } } +/** + * 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) +{ + /* 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 */ + pid = -1; + return true; + } + /* Wait 50 milliseconds. */ + CSleep(50); + } + + return false; +} + void MusicDriver_ExtMidi::DoStop() { 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) { - /* It has shut down, so we are done */ - this->pid = -1; - return; - } - /* Wait 10 milliseconds. */ - CSleep(10); - } + 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