Browse Source

Install signal handlers which push the signal to the top process which will try to gracefully shut down each child process

master
Con Kolivas 11 years ago
parent
commit
a615b56d76
  1. 59
      src/ckpool.c
  2. 2
      src/connector.c
  3. 6
      src/generator.c
  4. 5
      src/libckpool.c
  5. 18
      src/stratifier.c

59
src/ckpool.c

@ -134,6 +134,15 @@ static void rm_namepid(proc_instance_t *pi)
unlink(s);
}
/* Disable signal handlers for child processes, but simply pass them onto the
* parent process to shut down cleanly. */
static void childsighandler(int sig)
{
pid_t ppid = getppid();
kill(ppid, sig);
}
static void launch_process(proc_instance_t *pi)
{
pid_t pid;
@ -142,8 +151,15 @@ static void launch_process(proc_instance_t *pi)
if (pid < 0)
quit(1, "Failed to fork %s in launch_process", pi->processname);
if (!pid) {
struct sigaction handler;
int ret;
handler.sa_handler = &childsighandler;
handler.sa_flags = 0;
sigemptyset(&handler.sa_mask);
sigaction(SIGTERM, &handler, NULL);
sigaction(SIGINT, &handler, NULL);
rename_proc(pi->processname);
write_namepid(pi);
ret = pi->process(pi);
@ -160,23 +176,47 @@ static void clean_up(ckpool_t *ckp)
dealloc(ckp->socket_dir);
}
static void shutdown_children(ckpool_t *ckp, int sig)
static void __shutdown_children(ckpool_t *ckp, int sig)
{
pthread_cancel(ckp->pth_watchdog);
join_pthread(ckp->pth_watchdog);
if (!kill(ckp->generator.pid, 0))
kill(ckp->generator.pid, sig);
if (!kill(ckp->stratifier.pid, 0))
kill(ckp->stratifier.pid, sig);
if (!kill(ckp->connector.pid, 0))
kill(ckp->connector.pid, sig);
}
static void shutdown_children(ckpool_t *ckp, int sig)
{
pthread_cancel(ckp->pth_watchdog);
join_pthread(ckp->pth_watchdog);
__shutdown_children(ckp, sig);
}
static void sighandler(int sig)
{
pthread_cancel(global_ckp->pth_watchdog);
join_pthread(global_ckp->pth_watchdog);
/* First attempt, send a shutdown message */
send_proc(&global_ckp->generator, "shutdown");
send_proc(&global_ckp->stratifier, "shutdown");
send_proc(&global_ckp->connector, "shutdown");
if (sig != 9) {
shutdown_children(global_ckp, 15);
pthread_cancel(global_ckp->pth_listener);
/* Wait a second, then send SIGTERM */
sleep(1);
__shutdown_children(global_ckp, SIGTERM);
/* Wait another second, then send SIGKILL */
sleep(1);
__shutdown_children(global_ckp, SIGKILL);
pthread_cancel(global_ckp->pth_listener);
} else {
shutdown_children(global_ckp, 9);
__shutdown_children(global_ckp, SIGKILL);
exit(1);
}
}
@ -367,11 +407,6 @@ int main(int argc, char **argv)
/* Ignore sigpipe */
signal(SIGPIPE, SIG_IGN);
handler.sa_handler = &sighandler;
handler.sa_flags = 0;
sigemptyset(&handler.sa_mask);
sigaction(SIGTERM, &handler, NULL);
sigaction(SIGINT, &handler, NULL);
ret = mkdir(ckp.socket_dir, 0700);
if (ret && errno != EEXIST)
@ -408,6 +443,12 @@ int main(int argc, char **argv)
launch_process(&ckp.stratifier);
launch_process(&ckp.connector);
handler.sa_handler = &sighandler;
handler.sa_flags = 0;
sigemptyset(&handler.sa_mask);
sigaction(SIGTERM, &handler, NULL);
sigaction(SIGINT, &handler, NULL);
test_functions(&ckp);
create_pthread(&ckp.pth_watchdog, watchdog, &ckp);

2
src/connector.c

@ -512,5 +512,5 @@ out:
send_proc(&ckp->main, "shutdown");
sleep(1);
}
return ret;
exit(ret);
}

6
src/generator.c

@ -46,8 +46,10 @@ retry:
goto retry;
}
LOGDEBUG("Generator received request: %s", buf);
if (!strncasecmp(buf, "shutdown", 8))
if (!strncasecmp(buf, "shutdown", 8)) {
ret = 0;
goto out;
}
if (!strncasecmp(buf, "getbase", 7)) {
if (!gen_gbtbase(cs, &gbt)) {
LOGWARNING("Failed to get block template from %s:%s",
@ -154,5 +156,5 @@ out:
send_proc(&ckp->main, "shutdown");
sleep(1);
}
return ret;
exit(ret);
}

5
src/libckpool.c

@ -56,10 +56,7 @@ void create_pthread(pthread_t *thread, void *(*start_routine)(void *), void *arg
void join_pthread(pthread_t thread)
{
int ret = pthread_join(thread, NULL);
if (unlikely(ret))
quit(1, "Failed to pthread_join");
pthread_join(thread, NULL);
}

18
src/stratifier.c

@ -582,7 +582,7 @@ static void drop_client(int id)
ck_uilock(&instance_lock);
}
static int strat_loop(ckpool_t *ckp, proc_instance_t *pi)
static int stratum_loop(ckpool_t *ckp, proc_instance_t *pi)
{
int sockd, ret = 0, selret;
unixsock_t *us = &pi->us;
@ -626,9 +626,10 @@ retry:
goto retry;
}
LOGDEBUG("Stratifier received request: %s", buf);
if (!strncasecmp(buf, "shutdown", 8))
if (!strncasecmp(buf, "shutdown", 8)) {
ret = 0;
goto out;
else if (!strncasecmp(buf, "update", 6)) {
} else if (!strncasecmp(buf, "update", 6)) {
update_base(ckp);
goto reset;
} else if (!strncasecmp(buf, "dropclient", 10)) {
@ -1422,7 +1423,7 @@ int stratifier(proc_instance_t *pi)
pthread_t pth_blockupdate, pth_stratum_receiver, pth_stratum_sender;
pthread_t pth_statsupdate;
ckpool_t *ckp = pi->ckp;
int ret = 0;
int ret;
/* Store this for use elsewhere */
hex2bin(scriptsig_header_bin, scriptsig_header, 41);
@ -1450,7 +1451,12 @@ int stratifier(proc_instance_t *pi)
cklock_init(&share_lock);
strat_loop(ckp, pi);
ret = stratum_loop(ckp, pi);
LOGINFO("%s stratifier exiting with return code %d", ckp->name, ret);
if (ret) {
send_proc(&ckp->main, "shutdown");
sleep(1);
}
return ret;
exit(ret);
}

Loading…
Cancel
Save