aboutsummaryrefslogtreecommitdiffstats
path: root/src/sig_handlers.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/sig_handlers.c')
-rw-r--r--src/sig_handlers.c81
1 files changed, 78 insertions, 3 deletions
diff --git a/src/sig_handlers.c b/src/sig_handlers.c
index a3bf93050..364636e7c 100644
--- a/src/sig_handlers.c
+++ b/src/sig_handlers.c
@@ -19,6 +19,7 @@
#include "sig_handlers.h"
#include "player.h"
+#include "playerData.h"
#include "playlist.h"
#include "directory.h"
#include "command.h"
@@ -33,10 +34,30 @@
#include <sys/resource.h>
#include <sys/wait.h>
#include <errno.h>
+#include <unistd.h>
+
+extern volatile int masterPid;
+extern volatile int mainPid;
+
+int masterHandlePendingSignals() {
+ if(signal_is_pending(SIGINT) || signal_is_pending(SIGTERM)) {
+ DEBUG("master process got SIGINT or SIGTERM, exiting\n");
+ return COMMAND_RETURN_KILL;
+ }
+
+ if(signal_is_pending(SIGHUP)) {
+ signal_clear(SIGHUP);
+ /* Forward it to the main process, which will update the DB */
+ kill(mainPid, SIGHUP);
+ }
+
+
+ return 0;
+}
int handlePendingSignals() {
if(signal_is_pending(SIGINT) || signal_is_pending(SIGTERM)) {
- DEBUG("got SIGINT or SIGTERM, exiting\n");
+ DEBUG("main process got SIGINT or SIGTERM, exiting\n");
return COMMAND_RETURN_KILL;
}
@@ -57,17 +78,55 @@ int handlePendingSignals() {
void chldSigHandler(int signal) {
int status;
int pid;
- DEBUG("got SIGCHLD\n");
+ DEBUG("main process got SIGCHLD\n");
while(0 != (pid = wait3(&status,WNOHANG,NULL))) {
if(pid<0) {
if(errno==EINTR) continue;
else break;
}
- player_sigChldHandler(pid,status);
directory_sigChldHandler(pid,status);
}
}
+void masterChldSigHandler(int signal) {
+ int status;
+ int pid;
+ DEBUG("master process got SIGCHLD\n");
+ while(0 != (pid = wait3(&status,WNOHANG,NULL))) {
+ if(pid<0) {
+ if(errno==EINTR) continue;
+ else break;
+ }
+ DEBUG("PID: %d\n",pid);
+ if (pid == mainPid) kill(getpid(), SIGTERM);
+ player_sigChldHandler(pid,status);
+ }
+}
+
+int playerInitReal();
+
+void masterSigUsr2Handler(int signal) {
+ DEBUG("Master process got SIGUSR2 starting a new player process\n");
+ if (getPlayerPid() <= 0)
+ playerInitReal();
+}
+
+void masterInitSigHandlers() {
+ struct sigaction sa;
+
+ sa.sa_flags = 0;
+ sa.sa_handler = SIG_IGN;
+ while(sigaction(SIGPIPE,&sa,NULL)<0 && errno==EINTR);
+ sa.sa_handler = masterChldSigHandler;
+ while(sigaction(SIGCHLD,&sa,NULL)<0 && errno==EINTR);
+ sa.sa_handler = masterSigUsr2Handler;
+ while(sigaction(SIGUSR2,&sa,NULL)<0 && errno==EINTR);
+ signal_handle(SIGUSR1);
+ signal_handle(SIGINT);
+ signal_handle(SIGTERM);
+ signal_handle(SIGHUP);
+}
+
void initSigHandlers() {
struct sigaction sa;
@@ -114,17 +173,32 @@ void ignoreSignals() {
while(sigaction(SIGPIPE,&sa,NULL)<0 && errno==EINTR);
while(sigaction(SIGCHLD,&sa,NULL)<0 && errno==EINTR);
while(sigaction(SIGUSR1,&sa,NULL)<0 && errno==EINTR);
+ while(sigaction(SIGUSR2,&sa,NULL)<0 && errno==EINTR);
while(sigaction(SIGINT,&sa,NULL)<0 && errno==EINTR);
while(sigaction(SIGTERM,&sa,NULL)<0 && errno==EINTR);
while(sigaction(SIGHUP,&sa,NULL)<0 && errno==EINTR);
}
+void waitOnSignals() {
+ sigset_t sset;
+
+ sigfillset(&sset);
+ sigdelset(&sset,SIGCHLD);
+ sigdelset(&sset,SIGUSR1);
+ sigdelset(&sset,SIGUSR2);
+ sigdelset(&sset,SIGHUP);
+ sigdelset(&sset,SIGINT);
+ sigdelset(&sset,SIGTERM);
+ sigsuspend(&sset);
+}
+
void blockSignals() {
sigset_t sset;
sigemptyset(&sset);
sigaddset(&sset,SIGCHLD);
sigaddset(&sset,SIGUSR1);
+ sigaddset(&sset,SIGUSR2);
sigaddset(&sset,SIGHUP);
sigaddset(&sset,SIGINT);
sigaddset(&sset,SIGTERM);
@@ -137,6 +211,7 @@ void unblockSignals() {
sigemptyset(&sset);
sigaddset(&sset,SIGCHLD);
sigaddset(&sset,SIGUSR1);
+ sigaddset(&sset,SIGUSR2);
sigaddset(&sset,SIGHUP);
sigaddset(&sset,SIGINT);
sigaddset(&sset,SIGTERM);