From 20865004059cf044516c18657d2fceca4db3a701 Mon Sep 17 00:00:00 2001 From: "roberto@goyle" Date: Tue, 15 Nov 2011 18:06:37 +0100 Subject: [PATCH] added signal plugin --- buildconf/default.ini | 2 +- plugins/python/uwsgi_pymodule.c | 22 +++++++++++++---- plugins/signal/signal_plugin.c | 32 +++++++++++++++++++++++++ plugins/signal/uwsgiplugin.py | 7 ++++++ signal.c | 42 +++++++++++++++++++++++++++++++++ uwsgi.h | 1 + 6 files changed, 101 insertions(+), 5 deletions(-) create mode 100644 plugins/signal/signal_plugin.c create mode 100644 plugins/signal/uwsgiplugin.py diff --git a/buildconf/default.ini b/buildconf/default.ini index 9df52864..8d316221 100644 --- a/buildconf/default.ini +++ b/buildconf/default.ini @@ -27,7 +27,7 @@ plugins = bin_name = uwsgi append_version = plugin_dir = . -embedded_plugins = python, ping, cache, nagios, rrdtool, carbon, rpc, fastrouter, http, ugreen +embedded_plugins = python, ping, cache, nagios, rrdtool, carbon, rpc, fastrouter, http, ugreen, signal as_shared_library = false locking = auto diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index 47f57863..201319fb 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -518,17 +518,31 @@ PyObject *py_uwsgi_register_signal(PyObject * self, PyObject * args) { PyObject *py_uwsgi_signal(PyObject * self, PyObject * args) { uint8_t uwsgi_signal; + char *remote = NULL; - if (!PyArg_ParseTuple(args, "B:signal", &uwsgi_signal)) { + if (!PyArg_ParseTuple(args, "B|s:signal", &uwsgi_signal, &remote)) { return NULL; } + if (remote) { #ifdef UWSGI_DEBUG - uwsgi_log("sending %d to master\n", uwsgi_signal); + uwsgi_log("sending signal %d to node %s\n", uwsgi_signal, remote); #endif + int ret = uwsgi_remote_signal_send(remote, uwsgi_signal); + if (ret == 1) goto clear; + if (ret == -1) + return PyErr_Format(PyExc_IOError, "unable to deliver signal %d to node %s", uwsgi_signal, remote); + if (ret == 0) + return PyErr_Format(PyExc_ValueError, "node %s rejected signal %d", remote, uwsgi_signal); + } + else { +#ifdef UWSGI_DEBUG + uwsgi_log("sending signal %d to master\n", uwsgi_signal); +#endif + uwsgi_signal_send(uwsgi.signal_socket, uwsgi_signal); + } - uwsgi_signal_send(uwsgi.signal_socket, uwsgi_signal); - +clear: Py_INCREF(Py_None); return Py_None; diff --git a/plugins/signal/signal_plugin.c b/plugins/signal/signal_plugin.c new file mode 100644 index 00000000..6a54bccc --- /dev/null +++ b/plugins/signal/signal_plugin.c @@ -0,0 +1,32 @@ +#include "../../uwsgi.h" + +extern struct uwsgi_server uwsgi; + +/* request 110 */ +int uwsgi_request_signal(struct wsgi_request *wsgi_req) { + + ssize_t len; + uint8_t ret_status = 1; + if (uwsgi_signal_send(uwsgi.signal_socket, wsgi_req->uh.modifier2) < 0) { + ret_status = 0; + } + + wsgi_req->uh.modifier1 = 255; + wsgi_req->uh.pktsize = 0; + wsgi_req->uh.modifier2 = ret_status; + len = write(wsgi_req->poll.fd, wsgi_req, 4); + if (len != 4) { + uwsgi_error("write()"); + } + return UWSGI_OK; +} + + +struct uwsgi_plugin signal_plugin = { + + .name = "signal", + .modifier1 = 110, + .request = uwsgi_request_signal, + +}; + diff --git a/plugins/signal/uwsgiplugin.py b/plugins/signal/uwsgiplugin.py new file mode 100644 index 00000000..4af6764d --- /dev/null +++ b/plugins/signal/uwsgiplugin.py @@ -0,0 +1,7 @@ + +NAME='signal' +CFLAGS = [] +LDFLAGS = [] +LIBS = [] + +GCC_LIST = ['signal_plugin'] diff --git a/signal.c b/signal.c index 385180ee..752cb130 100644 --- a/signal.c +++ b/signal.c @@ -224,6 +224,48 @@ void create_signal_pipe(int *sigpipe) { } } +int uwsgi_remote_signal_send(char *addr, uint8_t sig) { + + struct uwsgi_header uh; + size_t remains = 4; + char *ptr = (char *) &uh; + + uh.modifier1 = 110; + uh.pktsize = 0; + uh.modifier2 = sig; + + int fd = uwsgi_connect(addr, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT], 0); + if (fd < 0) return -1; + + if (write(fd, (char *) &uh, 4) != 4) { + uwsgi_error("uwsgi_remote_signal_send()"); + close(fd); + return -1; + } + + while(remains > 0) { + int rlen = uwsgi_waitfd(fd, uwsgi.shared->options[UWSGI_OPTION_SOCKET_TIMEOUT]); + if (rlen > 0) { + ssize_t len = read(fd, ptr, remains); + if (len <= 0) { + break; + } + remains -= len; + ptr += len; + if (remains == 0) { + close(fd); + return uh.modifier2; + } + continue; + } + break; + } + + close(fd); + return -1; + +} + int uwsgi_signal_send(int fd, uint8_t sig) { socklen_t so_bufsize_len = sizeof(int); diff --git a/uwsgi.h b/uwsgi.h index e4dae12f..01d5cda7 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -2456,6 +2456,7 @@ ssize_t uwsgi_mule_get_msg(int, int, char *, size_t, int); uint8_t uwsgi_signal_wait(int); void uwsgi_add_app(int, uint8_t, char *, int); int uwsgi_signal_send(int, uint8_t); +int uwsgi_remote_signal_send(char *, uint8_t); #ifdef UWSGI_CAP void uwsgi_build_cap(char *);