Skip to content

Commit f41c7c3

Browse files
authored
Merge pull request unbit#2654 from methane/graceful-stop
`gracefully_kill()` uses pipe to stop worker loop
2 parents 8d3bcc2 + 71a492f commit f41c7c3

File tree

3 files changed

+26
-7
lines changed

3 files changed

+26
-7
lines changed

core/loop.c

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -127,6 +127,7 @@ void *simple_loop_run(void *arg1) {
127127
int main_queue = event_queue_init();
128128

129129
uwsgi_add_sockets_to_queue(main_queue, core_id);
130+
event_queue_add_fd_read(main_queue, uwsgi.loop_stop_pipe[0]);
130131

131132
if (uwsgi.signal_socket > -1) {
132133
event_queue_add_fd_read(main_queue, uwsgi.signal_socket);

core/uwsgi.c

Lines changed: 23 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1255,16 +1255,17 @@ void gracefully_kill(int signum) {
12551255

12561256
uwsgi_log("Gracefully killing worker %d (pid: %d)...\n", uwsgi.mywid, uwsgi.mypid);
12571257
uwsgi.workers[uwsgi.mywid].manage_next_request = 0;
1258+
12581259
if (uwsgi.threads > 1) {
1259-
struct wsgi_request *wsgi_req = current_wsgi_req();
1260-
wait_for_threads();
1261-
if (!uwsgi.workers[uwsgi.mywid].cores[wsgi_req->async_id].in_request) {
1262-
if (uwsgi.workers[uwsgi.mywid].shutdown_sockets)
1263-
uwsgi_shutdown_all_sockets();
1264-
exit(UWSGI_RELOAD_CODE);
1260+
// Stop event_queue_wait() in other threads.
1261+
// We use loop_stop_pipe only in threaded workers to avoid
1262+
// unintensional behavior changes in single threaded workers.
1263+
int fd;
1264+
if ((fd = uwsgi.loop_stop_pipe[1]) > 0) {
1265+
close(fd);
1266+
uwsgi.loop_stop_pipe[1] = 0;
12651267
}
12661268
return;
1267-
// never here
12681269
}
12691270

12701271
// still not found a way to gracefully reload in async mode
@@ -1296,6 +1297,17 @@ static void simple_goodbye_cruel_world(const char *reason) {
12961297
// Avoid showing same message from all threads.
12971298
uwsgi_log("...The work of process %d is done (%s). Seeya!\n", getpid(), (reason != NULL ? reason : "no reason given"));
12981299
}
1300+
1301+
if (uwsgi.threads > 1) {
1302+
// Stop event_queue_wait() in other threads.
1303+
// We use loop_stop_pipe only in threaded workers to avoid
1304+
// unintensional behavior changes in single threaded workers.
1305+
int fd;
1306+
if ((fd = uwsgi.loop_stop_pipe[1]) > 0) {
1307+
close(fd);
1308+
uwsgi.loop_stop_pipe[1] = 0;
1309+
}
1310+
}
12991311
}
13001312

13011313
void goodbye_cruel_world(const char *reason_fmt, ...) {
@@ -3641,6 +3653,10 @@ void uwsgi_ignition() {
36413653
exit(1);
36423654
}
36433655
}
3656+
if (pipe(&uwsgi.loop_stop_pipe[0])) {
3657+
uwsgi_error("pipe()")
3658+
exit(1);
3659+
}
36443660

36453661
// mark the worker as "accepting" (this is a mark used by chain reloading)
36463662
uwsgi.workers[uwsgi.mywid].accepting = 1;

uwsgi.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2953,6 +2953,8 @@ struct uwsgi_server {
29532953
struct uwsgi_buffer *websockets_continuation_buffer;
29542954

29552955
uint64_t max_worker_lifetime_delta;
2956+
// This pipe is used to stop event_queue_wait() in threaded workers.
2957+
int loop_stop_pipe[2];
29562958
};
29572959

29582960
struct uwsgi_rpc {

0 commit comments

Comments
 (0)