diff --git a/master.c b/master.c index 8e05e6e6..062b754b 100644 --- a/master.c +++ b/master.c @@ -421,14 +421,7 @@ void master_loop(char **argv, char **environ) { if (interesting_fd == ushared->files_monitored[i].fd) { struct uwsgi_fmon *uf = event_queue_ack_file_monitor(interesting_fd); // now call the file_monitor handler - if (uf) { - uwsgi_log("fd event for %s (signal %d)\n", uf->filename, uf->sig); - - struct uwsgi_signal_entry *use = &ushared->signal_table[uf->sig]; - if (use->kind == SIGNAL_KIND_WORKER) { - uwsgi_log("write signal returned %d\n", write(ushared->worker_signal_pipe[0], &uf->sig, 1)); - } - } + if (uf) uwsgi_route_signal(uf->sig); break; } } @@ -445,13 +438,7 @@ void master_loop(char **argv, char **environ) { if (interesting_fd == ushared->timers[i].fd) { struct uwsgi_timer *ut = event_queue_ack_timer(interesting_fd); // now call the file_monitor handler - if (ut) { - uwsgi_log("fd event for timer %d\n", ut->value); - struct uwsgi_signal_entry *use = &ushared->signal_table[ut->sig]; - if (use->kind == SIGNAL_KIND_WORKER) { - uwsgi_log("write signal returned %d\n", write(ushared->worker_signal_pipe[0], &ut->sig, 1)); - } - } + if (ut) uwsgi_route_signal(ut->sig); break; } } @@ -467,11 +454,7 @@ void master_loop(char **argv, char **environ) { } else if (rlen > 0) { uwsgi_log("received uwsgi signal %d from workers\n", uwsgi_signal); - // use uwsgi_route_signal() - struct uwsgi_signal_entry *use = &uwsgi.shared->signal_table[uwsgi_signal]; - if (use->kind == SIGNAL_KIND_WORKER) { - uwsgi_log("write signal returned %d\n", write(uwsgi.shared->worker_signal_pipe[0], &uwsgi_signal, 1)); - } + uwsgi_route_signal(uwsgi_signal); } else { uwsgi_log_verbose("lost connection with worker %d\n", i); diff --git a/plugins/lua/lua_plugin.c b/plugins/lua/lua_plugin.c index 4c832536..3a5d0fc2 100644 --- a/plugins/lua/lua_plugin.c +++ b/plugins/lua/lua_plugin.c @@ -137,6 +137,34 @@ static int uwsgi_api_cache_set(lua_State *L) { } +static int uwsgi_api_register_signal(lua_State *L) { + + int args = lua_gettop(L); + uint8_t sig, kind; + const void *handler; + const char *payload; + size_t payload_size; + + if (args >= 3) { + + sig = lua_tonumber(L, 1); + kind = lua_tonumber(L, 2); + lua_pushvalue(L, 3); + handler = (void *) luaL_ref(L, LUA_REGISTRYINDEX); + + if (args > 3) { + payload = lua_tolstring(L, 4, &payload_size); + uwsgi_register_signal(sig, kind, (void *) handler, 6, (char *) payload, payload_size); + } + else { + uwsgi_register_signal(sig, kind, (void *) handler, 6, NULL, 0); + } + } + + lua_pushnil(L); + return 1; +} + static int uwsgi_api_cache_get(lua_State *L) { @@ -257,6 +285,7 @@ static const luaL_reg uwsgi_api[] = { {"send_message", uwsgi_api_send_message}, {"cache_get", uwsgi_api_cache_get}, {"cache_set", uwsgi_api_cache_set}, + {"register_signal", uwsgi_api_register_signal}, {NULL, NULL} }; @@ -542,6 +571,37 @@ int uwsgi_lua_magic(char *mountpoint, char *lazy) { return 0; } +int uwsgi_lua_signal_handler(uint8_t sig, void *handler, char *payload, uint8_t payload_size) { + + struct wsgi_request *wsgi_req = current_wsgi_req(); + + lua_State *L = ulua.L[wsgi_req->async_id]; + + uwsgi_log("managing signal handler on core %d\n", wsgi_req->async_id); + + lua_rawgeti(L, LUA_REGISTRYINDEX, (int) handler); + + lua_pushnumber(L, sig); + if (!payload_size) { + lua_pushlstring(L, "", 0); + } + else { + lua_pushlstring(L, payload, payload_size); + } + + + if (lua_pcall(L, 2, 1, 0) != 0) { + uwsgi_log("error running function `f': %s", + lua_tostring(L, -1)); + + return -1; + + } + + return 0; + +} + struct uwsgi_plugin lua_plugin = { .name = "lua", @@ -553,6 +613,7 @@ struct uwsgi_plugin lua_plugin = { .after_request = uwsgi_lua_after_request, .init_apps = uwsgi_lua_app, .magic = uwsgi_lua_magic, + .signal_handler = uwsgi_lua_signal_handler, }; diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 3e72a922..cbf6b6b5 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -533,6 +533,14 @@ void uwsgi_uwsgi_config(char *module) { exit(1); } + if (PyDict_SetItemString(up.embedded_dict, "KIND_NULL", PyInt_FromLong(KIND_NULL))) { PyErr_Print(); exit(1);} + if (PyDict_SetItemString(up.embedded_dict, "KIND_WORKER", PyInt_FromLong(KIND_WORKER))) { PyErr_Print(); exit(1);} + if (PyDict_SetItemString(up.embedded_dict, "KIND_EVENT", PyInt_FromLong(KIND_EVENT))) { PyErr_Print(); exit(1);} + if (PyDict_SetItemString(up.embedded_dict, "KIND_SPOOLER", PyInt_FromLong(KIND_SPOOLER))) { PyErr_Print(); exit(1);} + if (PyDict_SetItemString(up.embedded_dict, "KIND_ERLANG", PyInt_FromLong(KIND_ERLANG))) { PyErr_Print(); exit(1);} + if (PyDict_SetItemString(up.embedded_dict, "KIND_PROXY", PyInt_FromLong(KIND_PROXY))) { PyErr_Print(); exit(1);} + if (PyDict_SetItemString(up.embedded_dict, "KIND_MASTER", PyInt_FromLong(KIND_MASTER))) { PyErr_Print(); exit(1);} + PyObject *py_opt_dict = PyDict_New(); for(i=0;ikey)) ) { diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index e4b0aba2..f8429ba8 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -166,8 +166,6 @@ PyObject *py_uwsgi_register_timer(PyObject * self, PyObject * args) { return NULL; } - uwsgi_log("signal_kind %d\n", signal_kind); - uwsgi_register_timer(uwsgi_signal, secs, signal_kind, handler, 0); Py_INCREF(Py_None); @@ -186,8 +184,6 @@ PyObject *py_uwsgi_register_file_monitor(PyObject * self, PyObject * args) { return NULL; } - uwsgi_log("signal_kind %d\n", signal_kind); - uwsgi_register_file_monitor(uwsgi_signal, filename, signal_kind, handler, 0); Py_INCREF(Py_None); @@ -205,7 +201,6 @@ PyObject *py_uwsgi_register_signal(PyObject * self, PyObject * args) { return NULL; } - uwsgi_log("REGISTER SIGNAL %d\n", uwsgi_signal); if (payload == NULL) { uwsgi_register_signal(uwsgi_signal, signal_kind, handler, 0, NULL, 0); } diff --git a/signal.c b/signal.c index 498c213a..ddcd462e 100644 --- a/signal.c +++ b/signal.c @@ -35,42 +35,6 @@ void uwsgi_register_signal(uint8_t sig, uint8_t kind, void *handler, uint8_t mod use->payload_size = payload_size; - /* - switch(sig) { - - case 10: - if (uwsgi.files_monitored_cnt < 64) { - uwsgi.files_monitored[uwsgi.files_monitored_cnt].filename = uwsgi_concat2(payload,""); - uwsgi.files_monitored[uwsgi.files_monitored_cnt].registered = 0; - // master is not running - if (uwsgi.master_queue != -1) { - uwsgi.files_monitored[uwsgi.files_monitored_cnt].fd = event_queue_add_file_monitor(uwsgi.master_queue, payload, &uwsgi.files_monitored[uwsgi.files_monitored_cnt].id); - uwsgi.files_monitored[uwsgi.files_monitored_cnt].registered = 1; - } - uwsgi.files_monitored_cnt++; - } - else { - uwsgi_log("you can register max 64 file monitors !!!\n"); - } - break; - case 11: - if (uwsgi.timers_cnt < 64) { - uwsgi.timers[uwsgi.timers_cnt].value = atoi(payload); - uwsgi.timers[uwsgi.timers_cnt].registered = 0; - // master is not running - if (uwsgi.master_queue != -1) { - uwsgi.timers[uwsgi.timers_cnt].fd = event_queue_add_timer(uwsgi.master_queue, &uwsgi.timers[uwsgi.timers_cnt].id, uwsgi.timers[uwsgi.timers_cnt].value); - uwsgi.timers[uwsgi.timers_cnt].registered = 1; - } - uwsgi.timers_cnt++; - } - else { - uwsgi_log("you can register max 64 timers !!!\n"); - } - break; - } - */ - uwsgi_log("registered signal %d\n", sig); uwsgi_unlock(uwsgi.signal_table_lock); @@ -125,3 +89,17 @@ void uwsgi_register_timer(uint8_t sig, int secs, uint8_t kind, void *handler, ui uwsgi_unlock(uwsgi.timer_table_lock); } + + +void uwsgi_route_signal(uint8_t sig) { + + struct uwsgi_signal_entry *use = &ushared->signal_table[sig]; + switch(use->kind) { + case KIND_WORKER: + if (write(ushared->worker_signal_pipe[0], &sig, 1) != 1) { + uwsgi_error("write()"); + uwsgi_log("could not deliver signal %d to workers pool\n", sig); + } + break; + }; +} diff --git a/tests/sig.lua b/tests/sig.lua new file mode 100644 index 00000000..7a32ee70 --- /dev/null +++ b/tests/sig.lua @@ -0,0 +1,9 @@ +function hello_signal(sig, payload) + + print("i am Lua received signal " .. sig .. " with payload " .. payload) + +end + +uwsgi.register_signal(1, 1, hello_signal, "roberta") +uwsgi.register_signal(2, 1, hello_signal, "serena") +uwsgi.register_signal(3, 1, hello_signal, "alessandro") diff --git a/tests/signals.py b/tests/signals.py index c2a905ca..44ec55dd 100644 --- a/tests/signals.py +++ b/tests/signals.py @@ -14,13 +14,13 @@ def hello_timer(num, secs): print "%s seconds elapsed" % secs #uwsgi.register_signal(30, uwsgi.SIGNAL_KIND_WORKER, hello_signal) -uwsgi.register_signal(30, 1, hello_signal) -uwsgi.register_signal(22, 1, hello_signal2, "*** PAYLOAD FOO ***") +uwsgi.register_signal(30, uwsgi.KIND_WORKER, hello_signal) +uwsgi.register_signal(22, uwsgi.KIND_WORKER, hello_signal2, "*** PAYLOAD FOO ***") -uwsgi.register_file_monitor(17, "/tmp", 1, hello_file) -uwsgi.register_timer(26, 2, 1, hello_timer) -uwsgi.register_timer(17, 4, 1, hello_timer) -uwsgi.register_timer(5, 8, 1, hello_timer) +uwsgi.register_file_monitor(17, "/tmp", uwsgi.KIND_WORKER, hello_file) +uwsgi.register_timer(26, 2, uwsgi.KIND_WORKER, hello_timer) +uwsgi.register_timer(17, 4, uwsgi.KIND_WORKER, hello_timer) +uwsgi.register_timer(5, 8, uwsgi.KIND_WORKER, hello_timer) def application(env, start_response): diff --git a/utils.c b/utils.c index ff47e350..b18d2374 100644 --- a/utils.c +++ b/utils.c @@ -478,9 +478,9 @@ polling: } } else { - uwsgi_log_verbose("master sent signal %b to worker %d\n", uwsgi_signal, uwsgi.mywid); + uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid); if (uwsgi_signal_handler(uwsgi_signal)) { - uwsgi_log_verbose("error managing signal %b on worker %d\n", uwsgi_signal, uwsgi.mywid); + uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid); } } } diff --git a/uwsgi.h b/uwsgi.h index d659e482..e880f523 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -876,13 +876,13 @@ struct uwsgi_lb_group { int kind; }; -#define SIGNAL_KIND_NULL 0 -#define SIGNAL_KIND_WORKER 1 -#define SIGNAL_KIND_EVENT 2 -#define SIGNAL_KIND_SPOOLER 3 -#define SIGNAL_KIND_ERLANG 4 -#define SIGNAL_KIND_PROXY 5 -#define SIGNAL_KIND_MASTER 6 +#define KIND_NULL 0 +#define KIND_WORKER 1 +#define KIND_EVENT 2 +#define KIND_SPOOLER 3 +#define KIND_ERLANG 4 +#define KIND_PROXY 5 +#define KIND_MASTER 6 struct uwsgi_signal_entry { uint8_t kind; @@ -1323,3 +1323,5 @@ void uwsgi_register_signal(uint8_t, uint8_t, void *, uint8_t, char *, uint8_t); void uwsgi_register_file_monitor(uint8_t, char *, uint8_t, void *, uint8_t); void uwsgi_register_timer(uint8_t, int, uint8_t, void *, uint8_t); int uwsgi_signal_handler(uint8_t); + +void uwsgi_route_signal(uint8_t);