Skip to content
This repository has been archived by the owner on Dec 20, 2018. It is now read-only.

Commit

Permalink
master: send SIGKILL to all workers on master exit
Browse files Browse the repository at this point in the history
  • Loading branch information
indutny committed Nov 27, 2013
1 parent 8ec68ef commit 1030cef
Show file tree
Hide file tree
Showing 4 changed files with 81 additions and 4 deletions.
14 changes: 11 additions & 3 deletions src/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -44,14 +44,22 @@ struct bud_config_s {
int argc;
char** argv;
char exepath[1024];
uv_pipe_t ipc;
struct bud_server_s* server;
struct bud_worker_s* workers;
struct bud_logger_s* logger;

/* Master state */
struct {
uv_signal_t sigterm;
uv_signal_t sigint;
} signal;
struct bud_worker_s* workers;
int last_worker;
int pending_accept;

/* Used by client */
/* Worker state */
uv_pipe_t ipc;

/* Used by client.c */
char proxyline_fmt[256];

/* Options from config file */
Expand Down
4 changes: 4 additions & 0 deletions src/error.c
Original file line number Diff line number Diff line change
Expand Up @@ -87,6 +87,10 @@ bud_error_t bud_error_num(bud_error_code_t code, int ret) {
BUD_UV_ERROR("uv_timer_init(restart_timer)", err) \
case kBudErrSpawn: \
BUD_UV_ERROR("uv_spawn(worker)", err) \
case kBudErrSignalInit: \
BUD_UV_ERROR("uv_signal_init()", err) \
case kBudErrSignalStart: \
BUD_UV_ERROR("uv_signal_start()", err) \
case kBudErrTcpServerInit: \
BUD_UV_ERROR("uv_tcp_init(server)", err) \
case kBudErrPton: \
Expand Down
2 changes: 2 additions & 0 deletions src/error.h
Original file line number Diff line number Diff line change
Expand Up @@ -35,6 +35,8 @@ enum bud_error_code_e {
kBudErrIPCReadStart = 0x205,
kBudErrRestartTimer = 0x206,
kBudErrSpawn = 0x207,
kBudErrSignalInit = 0x208,
kBudErrSignalStart = 0x209,

/* Server errors */
kBudErrTcpServerInit = 0x300,
Expand Down
65 changes: 64 additions & 1 deletion src/master.c
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,9 @@ struct bud_master_msg_s {

#ifndef _WIN32
static int bud_daemonize(bud_error_t* err);
static bud_error_t bud_master_init_signals(bud_config_t* config);
static void bud_master_signal_close_cb(uv_handle_t* handle);
static void bud_master_signal_cb(uv_signal_t* handle, int signum);
#endif /* !_WIN32 */
static bud_error_t bud_master_spawn_worker(bud_worker_t* worker);
static void bud_master_kill_worker(bud_worker_t* worker,
Expand Down Expand Up @@ -51,6 +54,11 @@ bud_error_t bud_master(bud_config_t* config) {
if (config->is_daemon)
if (bud_daemonize(&err) != 0)
goto fatal;

/* Initialize signal watchers */
err = bud_master_init_signals(config);
if (!bud_is_ok(err))
goto fatal;
#endif /* !_WIN32 */

/* Create server and send it to all workers */
Expand Down Expand Up @@ -87,7 +95,14 @@ bud_error_t bud_master_finalize(bud_config_t* config) {
int i;

for (i = 0; i < config->worker_count; i++)
bud_master_kill_worker(&config->workers[i], 0, NULL);
if (config->workers[i].active)
bud_master_kill_worker(&config->workers[i], 0, NULL);

#ifndef _WIN32
uv_close((uv_handle_t*) &config->signal.sigterm, bud_master_signal_close_cb);
uv_close((uv_handle_t*) &config->signal.sigint, bud_master_signal_close_cb);
#endif /* !_WIN32 */

return bud_ok();
}

Expand Down Expand Up @@ -129,6 +144,53 @@ int bud_daemonize(bud_error_t* err) {

return 0;
}


bud_error_t bud_master_init_signals(bud_config_t* config) {
int r;
bud_error_t err;

config->signal.sigterm.data = config;
config->signal.sigint.data = config;

r = uv_signal_init(config->loop, &config->signal.sigterm);
if (r != 0) {
err = bud_error_num(kBudErrSignalInit, r);
goto fatal;
}
r = uv_signal_init(config->loop, &config->signal.sigint);
if (r != 0) {
err = bud_error_num(kBudErrSignalInit, r);
goto failed_sigint_init;
}

r = uv_signal_start(&config->signal.sigterm, bud_master_signal_cb, SIGTERM);
if (r == 0)
r = uv_signal_start(&config->signal.sigint, bud_master_signal_cb, SIGINT);
if (r != 0) {
err = bud_error_num(kBudErrSignalStart, r);
goto failed_sigint_init;
}

return bud_ok();

failed_sigint_init:
uv_close((uv_handle_t*) &config->signal.sigterm, bud_master_signal_close_cb);

fatal:
return err;
}


void bud_master_signal_close_cb(uv_handle_t* handle) {
/* No-op */
}


void bud_master_signal_cb(uv_signal_t* handle, int signum) {
/* Stop the loop and let finalize to be called */
uv_stop(handle->loop);
}
#endif /* !_WIN32 */


Expand Down Expand Up @@ -234,6 +296,7 @@ void bud_master_kill_worker(bud_worker_t* worker,
uint64_t delay,
bud_worker_kill_cb cb) {
int r;
ASSERT(worker->active, "Tried to kill inactive worker");

uv_process_kill(&worker->proc, SIGKILL);
worker->active = 0;
Expand Down

0 comments on commit 1030cef

Please sign in to comment.