From 18ed984a4bb0967b2636c4a0fee1805d3f5e23a9 Mon Sep 17 00:00:00 2001 Message-Id: <18ed984a4bb0967b2636c4a0fee1805d3f5e23a9.1714443478.git.mdw@distorted.org.uk> From: Mark Wooding Date: Sat, 24 Oct 2009 17:48:05 +0100 Subject: [PATCH] SIGTERM and wait for subprocesses on server shutdown. Organization: Straylight/Edgeware From: Richard Kettlewell --- lib/event.c | 32 ++++++++++++++++++++++++++++++++ lib/event.h | 2 ++ server/state.c | 16 ++++++++++++++++ 3 files changed, 50 insertions(+) diff --git a/lib/event.c b/lib/event.c index ee25024..0c1e99a 100644 --- a/lib/event.c +++ b/lib/event.c @@ -754,6 +754,38 @@ int ev_child_cancel(ev_source *ev, return 0; } +/** @brief Terminate and wait for all child processes + * @param ev Event loop + * + * Does *not* call the completion callbacks. Only used during teardown. + */ +void ev_child_killall(ev_source *ev) { + int n, rc, w; + + for(n = 0; n < ev->nchildren; ++n) { + if(kill(ev->children[n].pid, SIGTERM) < 0) { + error(errno, "sending SIGTERM to pid %lu", + (unsigned long)ev->children[n].pid); + ev->children[n].pid = -1; + } else + info("sent SIGTERM to pid %lu", (unsigned long)ev->children[n].pid); + } + for(n = 0; n < ev->nchildren; ++n) { + if(ev->children[n].pid == -1) + continue; + do { + rc = waitpid(ev->children[n].pid, &w, 0); + } while(rc < 0 && errno == EINTR); + if(rc < 0) { + error(errno, "waiting for pid %lu", (unsigned long)ev->children[n].pid); + continue; + } + info("pid %lu exited with status %#x", + (unsigned long)ev->children[n].pid, w); + } + ev->nchildren = 0; +} + /* socket listeners ***********************************************************/ /** @brief State for a socket listener */ diff --git a/lib/event.h b/lib/event.h index 2838c41..113666c 100644 --- a/lib/event.h +++ b/lib/event.h @@ -139,6 +139,8 @@ int ev_child_cancel(ev_source *ev, pid_t pid); /* cancel a child callback. */ +void ev_child_killall(ev_source *ev); + /* socket listeners ***********************************************************/ typedef int ev_listen_callback(ev_source *ev, diff --git a/server/state.c b/server/state.c index bd74b14..47bb75c 100644 --- a/server/state.c +++ b/server/state.c @@ -50,6 +50,22 @@ void quit(ev_source *ev) { quitting(ev); trackdb_close(); trackdb_deinit(); + /* Shutdown subprocesses. + * + * Subprocesses that use ev_child: + * - the speaker + * - the current rescan + * - any decoders + * - ...and players + * - the track picker + * - mail sender + * - the deadlock manager + * + * Subprocesses that don't: + * - any normalizers + * These are not shut down currently. + */ + ev_child_killall(ev); info("exiting"); exit(0); } -- [mdw]