diff --git a/src/driver.h b/src/driver.h --- a/src/driver.h +++ b/src/driver.h @@ -28,12 +28,13 @@ public: virtual ~Driver() { } + /** The type of driver */ enum Type { - DT_BEGIN = 0, - DT_SOUND = 0, - DT_MUSIC, - DT_VIDEO, - DT_END, + DT_BEGIN = 0, ///< Helper for iteration + DT_MUSIC = 0, ///< A music driver, needs to be before sound to properly shut down extmidi forked music players + DT_SOUND, ///< A sound driver + DT_VIDEO, ///< A video driver + DT_END, ///< Helper for iteration }; virtual const char *GetName() const = 0; @@ -64,7 +65,7 @@ private: static const char *GetDriverTypeName(Driver::Type type) { - static const char * const driver_type_name[] = { "sound", "music", "video" }; + static const char * const driver_type_name[] = { "music", "sound", "video" }; return driver_type_name[type]; } diff --git a/src/music/extmidi.cpp b/src/music/extmidi.cpp --- a/src/music/extmidi.cpp +++ b/src/music/extmidi.cpp @@ -15,6 +15,7 @@ #include "../string_func.h" #include "../sound/sound_driver.hpp" #include "../video/video_driver.hpp" +#include "../gfx_func.h" #include "extmidi.h" #include #include @@ -108,7 +109,27 @@ void MusicDriver_ExtMidi::DoPlay() void MusicDriver_ExtMidi::DoStop() { - if (this->pid != -1) kill(this->pid, SIGTERM); + 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, NULL, WNOHANG) == this->pid) { + /* It has shut down, so we are done */ + this->pid = -1; + return; + } + /* Wait 10 milliseconds. */ + CSleep(10); + } + + 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. */ + kill(this->pid, SIGKILL); + waitpid(this->pid, NULL, 0); + this->pid = -1; } #endif /* __MORPHOS__ */