diff --git a/core/master_utils.c b/core/master_utils.c index 32c0953e..be2eb7a2 100644 --- a/core/master_utils.c +++ b/core/master_utils.c @@ -980,6 +980,7 @@ void uwsgi_register_cheaper_algo(char *name, int (*func) (void)) { } void trigger_harakiri(int i) { + int j; uwsgi_log("*** HARAKIRI ON WORKER %d (pid: %d) ***\n", i, uwsgi.workers[i].pid); if (uwsgi.harakiri_verbose) { #ifdef __linux__ @@ -1017,6 +1018,17 @@ void trigger_harakiri(int i) { } if (uwsgi.workers[i].pid > 0) { + for (j = 0; j < uwsgi.gp_cnt; j++) { + if (uwsgi.gp[j]->harakiri) { + uwsgi.gp[j]->harakiri(i); + } + } + for (j = 0; j < 256; j++) { + if (uwsgi.p[j]->harakiri) { + uwsgi.p[j]->harakiri(i); + } + } + kill(uwsgi.workers[i].pid, SIGUSR2); // allow SIGUSR2 to be delivered sleep(1); diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index f6f48c63..737c9104 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -1755,6 +1755,30 @@ int uwsgi_python_mule_msg(char *message, size_t len) { return 1; } +void uwsgi_python_harakiri(int wid) { + + if (up.tracebacker) { + + char buf[8192]; + char *address = uwsgi_concat2(up.tracebacker, uwsgi_num2str(wid)); + + int fd = uwsgi_connect(address, -1, 0); + for (;;) { + int ret = uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + if (ret <= 0) { + break; + } + ssize_t len = read(fd, buf, 8192); + if (len <= 0) { + break; + } + uwsgi_log("%.*s", (int) len, buf); + } + + free(address); + } + +} #ifndef UWSGI_PYPY struct uwsgi_plugin python_plugin = { @@ -1789,6 +1813,8 @@ struct uwsgi_plugin pypy_plugin = { .resume = uwsgi_python_resume, #endif + .harakiri = uwsgi_python_harakiri, + .hijack_worker = uwsgi_python_hijack, .spooler_init = uwsgi_python_spooler_init, diff --git a/uwsgi.h b/uwsgi.h index 70f50e3c..8303ce4e 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -666,6 +666,8 @@ struct uwsgi_plugin { void (*suspend) (struct wsgi_request *); void (*resume) (struct wsgi_request *); + void (*harakiri) (int); + void (*hijack_worker) (void); void (*spooler_init) (void); void (*atexit) (void);