diff --git a/decoratortest.py b/decoratortest.py index f0f1e3b1..7f7398f4 100644 --- a/decoratortest.py +++ b/decoratortest.py @@ -84,6 +84,9 @@ def fork_happened(): @postfork def fork_happened2(): + print("waiting for a signal...") + uwsgi.signal_wait() + print("signal received: %d" % uwsgi.signal_received()) print("fork() has been called [2] wid: %d" % uwsgi.worker_id()) @postfork diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index 98741d5d..744a96f3 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -10,8 +10,44 @@ extern struct uwsgi_python up; PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) { struct wsgi_request *wsgi_req = current_wsgi_req(); + int wait_for_specific_signal = 0; + uint8_t uwsgi_signal = 0; + uint8_t received_signal; + int ret; + + wsgi_req->signal_received = -1; + + if (PyTuple_Size(args) > 0) { + if (!PyArg_ParseTuple(args, "|B:", &uwsgi_signal)) { + return NULL; + } + wait_for_specific_signal = 1; + } + +#ifdef UWSGI_ASYNC + if (uwsgi.async > 1) { + wsgi_req->sigwait = 1; + } + else { +#endif +cycle: + ret = uwsgi_waitfd(uwsgi.signal_socket, -1); + if (ret > 0) { + if (read(uwsgi.signal_socket, &received_signal, 1) != 1) { + uwsgi_error("read()"); + } + else { + wsgi_req->signal_received = received_signal; + if (wait_for_specific_signal) { + if (received_signal != uwsgi_signal) goto cycle; + } + } + } + +#ifdef UWSGI_ASYNC + } +#endif - wsgi_req->sigwait = 1; return PyString_FromString(""); } diff --git a/sigwait.py b/sigwait.py new file mode 100644 index 00000000..f5a8cefe --- /dev/null +++ b/sigwait.py @@ -0,0 +1,23 @@ +import uwsgi +from uwsgidecorators import * + +@postfork +def wait_for_signal(): + if uwsgi.worker_id() == 2: + print("waiting for a signal...") + uwsgi.signal_wait() + print("signal %d received" % uwsgi.signal_received()) + elif uwsgi.worker_id() == 3: + print("waiting for signal 30...") + uwsgi.signal_wait(30) + print("signal %d received" % uwsgi.signal_received()) + + +def application(e, s): + s('200 OK', [('Content-Type', 'text/html')]) + if e['PATH_INFO'] == '/30': + uwsgi.signal(30) + else: + uwsgi.signal(17) + return "Signal raised" + diff --git a/spooler.c b/spooler.c index 71c9f637..05d1c4f7 100644 --- a/spooler.c +++ b/spooler.c @@ -32,6 +32,7 @@ pid_t spooler_start() { if (uwsgi.master_process) { close(uwsgi.shared->spooler_signal_pipe[0]); } + uwsgi.signal_socket = uwsgi.shared->spooler_signal_pipe[1]; spooler(); } else if (pid > 0) { diff --git a/uwsgi.h b/uwsgi.h index 3b0185f5..55136bb4 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -811,7 +811,7 @@ struct wsgi_request { int log_this; int sigwait; - uint8_t signal_received; + int signal_received; struct msghdr msg; union {