From 672c49e8eb12cfdbde46475d94c0e02307d303b7 Mon Sep 17 00:00:00 2001 From: "roberto@precise64" Date: Tue, 24 Apr 2012 21:27:43 +0200 Subject: [PATCH] refactored signal handling --- hello_world.py | 2 +- loop.c | 31 ++----------------------------- plugins/gevent/gevent.c | 33 +++++++-------------------------- runningthread.py | 2 ++ signal.c | 30 ++++++++++++++++++++++++++++++ spooler.c | 14 +------------- utils.c | 19 +------------------ uwsgi.h | 2 ++ 8 files changed, 46 insertions(+), 87 deletions(-) diff --git a/hello_world.py b/hello_world.py index c26de534..c296b791 100644 --- a/hello_world.py +++ b/hello_world.py @@ -14,7 +14,7 @@ def application(env, start_response): start_response('200 OK', [('Content-Type', 'text/html')]) yield "foobar
" if uwsgi.loop == 'gevent': - gevent.sleep(10) + gevent.sleep(3) yield str(env['wsgi.input'].fileno()) yield "

Hello World

" try: diff --git a/loop.c b/loop.c index 9cc00d73..4f591ef5 100644 --- a/loop.c +++ b/loop.c @@ -120,7 +120,6 @@ void *zeromq_loop(void *arg1) { struct wsgi_request *wsgi_req = uwsgi.wsgi_requests[core_id]; uwsgi.zeromq_recv_flag = 0; zmq_pollitem_t zmq_poll_items[3]; - char uwsgi_signal; if (uwsgi.threads > 1) { @@ -188,38 +187,12 @@ void *zeromq_loop(void *arg1) { } if (zmq_poll_items[1].revents & ZMQ_POLLIN) { - if (read(uwsgi.signal_socket, &uwsgi_signal, 1) <= 0) { - if (uwsgi.no_orphans) { - uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid); - end_me(0); - } - } - else { -#ifdef UWSGI_DEBUG - uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid); -#endif - if (uwsgi_signal_handler(uwsgi_signal)) { - uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid); - } - } + uwsgi_receive_signal(uwsgi.signal_socket, "worker", uwsgi.mywid); continue; } if (zmq_poll_items[2].revents & ZMQ_POLLIN) { - if (read(uwsgi.my_signal_socket, &uwsgi_signal, 1) <= 0) { - if (uwsgi.no_orphans) { - uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid); - end_me(0); - } - } - else { -#ifdef UWSGI_DEBUG - uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid); -#endif - if (uwsgi_signal_handler(uwsgi_signal)) { - uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid); - } - } + uwsgi_receive_signal(uwsgi.my_signal_socket, "worker", uwsgi.mywid); continue; } diff --git a/plugins/gevent/gevent.c b/plugins/gevent/gevent.c index 73c36589..d1d5022d 100644 --- a/plugins/gevent/gevent.c +++ b/plugins/gevent/gevent.c @@ -34,34 +34,20 @@ struct wsgi_request *uwsgi_gevent_current_wsgi_req(void) { PyObject *py_uwsgi_gevent_signal_handler(PyObject * self, PyObject * args) { - uint8_t uwsgi_signal; int signal_socket; if (!PyArg_ParseTuple(args, "i:uwsgi_gevent_signal_handler", &signal_socket)) { return NULL; } - if (read(signal_socket, &uwsgi_signal, 1) <= 0) { - if (uwsgi.no_orphans) { - uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid); - end_me(0); - } - // close the socket to end the mess...from now on the worker is alone (no master) - else close(signal_socket); - } - else { -#ifdef UWSGI_DEBUG - uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid); -#endif - if (uwsgi_signal_handler(uwsgi_signal)) { - uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid); - } - } + uwsgi_receive_signal(signal_socket, "worker", uwsgi.mywid); Py_INCREF(Py_None); return Py_None; } +// the following twi functions are called whenever an event is available in the signal queue +// they both trigger the same function PyObject *py_uwsgi_gevent_signal(PyObject * self, PyObject * args) { PyTuple_SetItem(ugevent.signal_args, 1, PyInt_FromLong(uwsgi.signal_socket)); @@ -99,8 +85,6 @@ PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) { goto clear; } - UWSGI_RELEASE_GIL - // fill wsgi_request structure wsgi_req_setup(wsgi_req, wsgi_req->async_id, uwsgi.sockets ); @@ -116,13 +100,10 @@ PyObject *py_uwsgi_gevent_main(PyObject * self, PyObject * args) { // accept the connection if (wsgi_req_simple_accept(wsgi_req, uwsgi.sockets->fd)) { - UWSGI_GET_GIL free_req_queue; goto clear; } - UWSGI_GET_GIL - // hack to easily pass wsgi_req pointer to the greenlet PyTuple_SetItem(ugevent.greenlet_args, 1, PyLong_FromLong((long)wsgi_req)); @@ -185,9 +166,7 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) { goto clear_and_stop; } else if (ret == watcher) { - UWSGI_RELEASE_GIL status = wsgi_req->socket->proto(wsgi_req); - UWSGI_GET_GIL if (status < 0) { goto clear_and_stop; } @@ -204,8 +183,6 @@ PyObject *py_uwsgi_gevent_request(PyObject * self, PyObject * args) { stop_the_watchers; } - UWSGI_RELEASE_GIL - for(;;) { wsgi_req->async_status = uwsgi.p[wsgi_req->uh.modifier1]->request(wsgi_req); if (wsgi_req->async_status <= UWSGI_OK) { @@ -251,6 +228,10 @@ void gevent_loop() { // get the GIL UWSGI_GET_GIL + // ..then reset GIL subsystem as noop (gevent IO will take care of it...) + up.gil_get = gil_fake_get; + up.gil_release = gil_fake_release; + struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; if (uwsgi.async < 2) { diff --git a/runningthread.py b/runningthread.py index 2447f35d..bcd4cfe0 100644 --- a/runningthread.py +++ b/runningthread.py @@ -1,9 +1,11 @@ from threading import Thread import time +import uwsgi def mess(): while True: for i in xrange(0, 100): + uwsgi.signal(17) print(i) time.sleep(0.1) diff --git a/signal.c b/signal.c index 14ef98ee..d18f92d3 100644 --- a/signal.c +++ b/signal.c @@ -559,3 +559,33 @@ cycle: return received_signal; } +void uwsgi_receive_signal(int fd, char *name, int id) { + + uint8_t uwsgi_signal; + + ssize_t ret = read(fd, &uwsgi_signal, 1); + + if (ret == 0) { + goto destroy; + } + else if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { + uwsgi_error("[uwsgi-signal] read()"); + goto destroy; + } + else if (ret > 0) { +#ifdef UWSGI_DEBUG + uwsgi_log_verbose("master sent signal %d to %s %d\n", uwsgi_signal, name, id); +#endif + if (uwsgi_signal_handler(uwsgi_signal)) { + uwsgi_log_verbose("error managing signal %d on %s %d\n", uwsgi_signal, name, id); + } + } + + return; + +destroy: + // better to kill the whole worker... + uwsgi_log_verbose("uWSGI %s %d screams: UAAAAAAH my master disconnected: i will kill myself !!!\n", name, id); + end_me(0); + +} diff --git a/spooler.c b/spooler.c index ed643478..0dc21baf 100644 --- a/spooler.c +++ b/spooler.c @@ -340,19 +340,7 @@ void spooler(struct uwsgi_spooler *uspool) { if (event_queue_wait(spooler_event_queue, timeout, &interesting_fd) > 0) { if (uwsgi.master_process) { if (interesting_fd == uwsgi.shared->spooler_signal_pipe[1]) { - uint8_t uwsgi_signal; - if (read(interesting_fd, &uwsgi_signal, 1) <= 0) { - uwsgi_log_verbose("uWSGI spooler screams: UAAAAAAH my master died, i will follow him...\n"); - end_me(0); - } - else { -#ifdef UWSGI_DEBUG - uwsgi_log_verbose("master sent signal %d to the spooler\n", uwsgi_signal); -#endif - if (uwsgi_signal_handler(uwsgi_signal)) { - uwsgi_log_verbose("error managing signal %d on the spooler\n", uwsgi_signal); - } - } + uwsgi_receive_signal(interesting_fd, "spooler", (int) getpid()); } } } diff --git a/utils.c b/utils.c index 9c92f41e..f7285e27 100644 --- a/utils.c +++ b/utils.c @@ -1018,7 +1018,6 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) { int ret; int interesting_fd; - char uwsgi_signal; struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; thunder_lock; @@ -1037,23 +1036,7 @@ int wsgi_req_accept(int queue, struct wsgi_request *wsgi_req) { thunder_unlock; - if (read(interesting_fd, &uwsgi_signal, 1) <= 0) { - if (uwsgi.no_orphans) { - uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid); - end_me(0); - } - else { - close(interesting_fd); - } - } - else { -#ifdef UWSGI_DEBUG - uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid); -#endif - if (uwsgi_signal_handler(uwsgi_signal)) { - uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid); - } - } + uwsgi_receive_signal(interesting_fd, "worker", uwsgi.mywid); #ifdef UWSGI_THREADING if (uwsgi.threads > 1) pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &ret); diff --git a/uwsgi.h b/uwsgi.h index 565517eb..c8a9f04e 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2819,6 +2819,8 @@ int uwsgi_try_autoload(char *); uint64_t uwsgi_micros(void); int uwsgi_is_file(char *); +void uwsgi_receive_signal(int, char *, int); + #ifdef UWSGI_AS_SHARED_LIBRARY int uwsgi_init(int, char **, char **); #endif