diff --git a/master.c b/master.c index bacc32f9..4380c4dd 100644 --- a/master.c +++ b/master.c @@ -187,11 +187,15 @@ void master_loop(char **argv, char **environ) { uwsgi.master_queue = event_queue_init(); +#ifdef UWSGI_DEBUG uwsgi_log("adding %d to signal poll\n", uwsgi.shared->worker_signal_pipe[0]); +#endif event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_signal_pipe[0]); if (uwsgi.log_master) { +#ifdef UWSGI_DEBUG uwsgi_log("adding %d to master logging\n", uwsgi.shared->worker_log_pipe[0]); +#endif event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_log_pipe[0]); } @@ -313,6 +317,27 @@ void master_loop(char **argv, char **environ) { for (;;) { //uwsgi_log("ready_to_reload %d %d\n", ready_to_reload, uwsgi.numproc); + + if (uwsgi.master_mercy) { + if (uwsgi.master_mercy < time(NULL)) { + for(i=1;i<=uwsgi.numproc;i++) { + if (uwsgi.workers[i].pid > 0) { + uwsgi_log("worker %d (pid: %d) is taking too much time to die...NO MERCY !!!\n", i, uwsgi.workers[i].pid); + if (!kill(uwsgi.workers[i].pid, SIGKILL)) { + if (waitpid(uwsgi.workers[i].pid, &waitpid_status, 0) < 0) { + uwsgi_error("waitpid()"); + } + uwsgi.workers[i].pid = 0; + if (uwsgi.to_hell) { ready_to_die++;} + else if (uwsgi.to_heaven) { ready_to_reload++;} + } + else { + uwsgi_error("kill()"); + } + } + } + } + } if (ready_to_die >= uwsgi.numproc && uwsgi.to_hell) { #ifdef UWSGI_SPOOLER if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { @@ -890,14 +915,14 @@ void master_loop(char **argv, char **environ) { if (uwsgi.to_heaven) { ready_to_reload++; - uwsgi.workers[uwsgi.mywid].pid = -1; + uwsgi.workers[uwsgi.mywid].pid = 0; // only to be safe :P uwsgi.workers[uwsgi.mywid].harakiri = 0; continue; } else if (uwsgi.to_hell) { ready_to_die++; - uwsgi.workers[uwsgi.mywid].pid = -1; + uwsgi.workers[uwsgi.mywid].pid = 0; // only to be safe :P uwsgi.workers[uwsgi.mywid].harakiri = 0; continue; diff --git a/plugins/python/pyloader.c b/plugins/python/pyloader.c index a62ec161..7a5a4785 100644 --- a/plugins/python/pyloader.c +++ b/plugins/python/pyloader.c @@ -308,8 +308,6 @@ int init_uwsgi_app(int loader, void *arg1, struct wsgi_request *wsgi_req, PyThre PyThreadState_Swap(up.main_thread); } - uwsgi_log("done\n"); - if (wi->argc == 1) { uwsgi_log( "Web3 application %d (SCRIPT_NAME=%.*s) ready on interpreter %p", id, wi->mountpoint_len, wi->mountpoint, wi->interpreter); } diff --git a/uwsgi.c b/uwsgi.c index fea69669..959797e0 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -58,6 +58,7 @@ static struct option long_base_options[] = { {"single-interpreter", no_argument, 0, 'i'}, {"master", no_argument, 0, 'M'}, {"emperor", required_argument, 0, LONG_ARGS_EMPEROR}, + {"reload-mercy", required_argument, 0, LONG_ARGS_RELOAD_MERCY}, {"help", no_argument, 0, 'h'}, {"reaper", no_argument, 0, 'r'}, {"max-requests", required_argument, 0, 'R'}, @@ -189,7 +190,7 @@ void warn_pipe() void gracefully_kill() { - uwsgi_log("Gracefully killing worker %d...\n", uwsgi.mypid); + uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid); if (UWSGI_IS_IN_REQUEST) { uwsgi.workers[uwsgi.mywid].manage_next_request = 0; } else { @@ -219,6 +220,7 @@ void kill_them_all() uwsgi.to_hell = 1; uwsgi_log("SIGINT/SIGQUIT received...killing workers...\n"); for (i = 1; i <= uwsgi.numproc; i++) { + if (uwsgi.workers[i].pid > 0) kill(uwsgi.workers[i].pid, SIGINT); } @@ -236,6 +238,9 @@ void grace_them_all() int i; uwsgi.to_heaven = 1; + if (uwsgi.reload_mercy > 0) { + uwsgi.master_mercy = time(NULL) + uwsgi.reload_mercy; + } for (i = 0; i < uwsgi.shared->daemons_cnt; i++) { kill(uwsgi.shared->daemons[i].pid, SIGKILL); @@ -243,6 +248,7 @@ void grace_them_all() uwsgi_log("...gracefully killing workers...\n"); for (i = 1; i <= uwsgi.numproc; i++) { + if (uwsgi.workers[i].pid > 0) kill(uwsgi.workers[i].pid, SIGHUP); } @@ -259,6 +265,7 @@ void reap_them_all() uwsgi_log("...brutally killing workers...\n"); for (i = 1; i <= uwsgi.numproc; i++) { + if (uwsgi.workers[i].pid > 0) kill(uwsgi.workers[i].pid, SIGTERM); } } @@ -1905,6 +1912,9 @@ end: case LONG_ARGS_EMPEROR: uwsgi.emperor_dir = optarg; return 1; + case LONG_ARGS_RELOAD_MERCY: + uwsgi.reload_mercy = atoi(optarg); + return 1; case LONG_ARGS_LOG_MASTER: uwsgi.log_master = 1; return 1; diff --git a/uwsgi.h b/uwsgi.h index 73a4abf7..e9037029 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -354,6 +354,7 @@ struct uwsgi_opt { #define LONG_ARGS_ATTACH_DAEMON 17077 #define LONG_ARGS_SUBSCRIBE_TO 17078 #define LONG_ARGS_CLUSTER_NODES 17079 +#define LONG_ARGS_RELOAD_MERCY 17080 @@ -712,6 +713,9 @@ struct uwsgi_server { char *emperor_dir; pid_t emperor_pid; + time_t master_mercy; + + int reload_mercy; int option_index; struct option *long_options; struct uwsgi_opt **exported_opts;