diff --git a/core/uwsgi.c b/core/uwsgi.c index 22283ffc..2e0ade40 100644 --- a/core/uwsgi.c +++ b/core/uwsgi.c @@ -2215,6 +2215,9 @@ int uwsgi_start(void *v_argv) { } #endif + // users of the --loop option should know what they are doing... really... + if (uwsgi.loop) goto unsafe; + #ifdef UWSGI_UDP if (!uwsgi.sockets && !ushared->gateways_cnt && !uwsgi.no_server && !uwsgi.udp_socket && !uwsgi.emperor && !uwsgi.command_mode) { #else @@ -2238,6 +2241,8 @@ int uwsgi_start(void *v_argv) { uwsgi.to_hell = 1; } +unsafe: + #ifdef UWSGI_DEBUG struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; int so_bufsize; diff --git a/hello_world.py b/hello_world.py index a8c13b93..aa688d8c 100644 --- a/hello_world.py +++ b/hello_world.py @@ -2,6 +2,36 @@ import uwsgi if uwsgi.loop == 'gevent': import gevent +from threading import Thread +import time +from uwsgidecorators import postfork + +def foobar(): + while True: + time.sleep(3) + print "threee second elapsed in worker %d" % uwsgi.worker_id() + +@postfork +def spawn_thread(): + t = Thread(target=foobar) + t.daemon = True + t.start() + +@postfork +def spawn_thread2(): + t = Thread(target=foobar) + t.daemon = True + t.start() + +def gl_func(): + while True: + gevent.sleep(2) + print "i am a greenltet running in worker %d" % uwsgi.worker_id() + +@postfork +def spawn_greenlet(): + gevent.spawn(gl_func) + print uwsgi.version print uwsgi.workers() try: diff --git a/plugins/dumbloop/dumb.c b/plugins/dumbloop/dumb.c new file mode 100644 index 00000000..204e4b27 --- /dev/null +++ b/plugins/dumbloop/dumb.c @@ -0,0 +1,69 @@ +#include "../../uwsgi.h" + +extern struct uwsgi_server uwsgi; + +// global variables for configuration +static uint8_t dumbloop_modifier1 = 0; +static char *dumbloop_code = ""; +static char *dumbloop_function = "dumbloop"; + +struct uwsgi_option dumbloop_options[] = { + {"dumbloop-modifier1", required_argument, 0, "set the modifier1 for the code_string", uwsgi_opt_set_int, &dumbloop_modifier1, 0}, + {"dumbloop-code", required_argument, 0, "set the script to load for the code_string", uwsgi_opt_set_str, &dumbloop_code, 0}, + {"dumbloop-function", required_argument, 0, "set the function to run for the code_string", uwsgi_opt_set_str, &dumbloop_function, 0}, + {0, 0, 0, 0, 0, 0, 0}, + +}; + + +// this function is executed for each thread +static void *dumb_loop_run(void *arg1) { + + // get the core id (pthreads take a void pointer as argument, so we need this ugly trick) + long core_id = (long) arg1; + +#ifdef UWSGI_THREADING + // complete threads setup (this is required for fixing things like UNIX signal handling) + if (uwsgi.threads > 1) { + // wsgi_request mapped to the core + struct wsgi_request *wsgi_req = &uwsgi.workers[uwsgi.mywid].cores[core_id].req; + // fix it + uwsgi_setup_thread_req(core_id, wsgi_req); + } +#endif + + // this strign will be passed to the code_string function + char *str_core = uwsgi_num2str(core_id); + // ok we are ready, let's run custom code + while (uwsgi.workers[uwsgi.mywid].manage_next_request) { + if (uwsgi.p[dumbloop_modifier1]->code_string) { + // "uwsgi_dumbloop" is the name of the module (will be used while importing the file, if needed) + uwsgi.p[dumbloop_modifier1]->code_string("uwsgi_dumbloop", dumbloop_code, dumbloop_function, str_core, strlen(str_core)); + } + else { + uwsgi_log("the requested plugin does not support code_string hook\n"); + exit(1); + } + } + + return NULL; +} + +static void dumb_loop() { + // this run the dumb_loop_run in each thread (core) + uwsgi_loop_cores_run(dumb_loop_run); +} + + + +// register the new loop engine +static void dumbloop_register() { + uwsgi_register_loop( (char *) "dumb", dumb_loop); +} + + +struct uwsgi_plugin dumbloop_plugin = { + .name = "dumbloop", + .on_load = dumbloop_register, + .options = dumbloop_options, +}; diff --git a/plugins/dumbloop/uwsgiplugin.py b/plugins/dumbloop/uwsgiplugin.py new file mode 100644 index 00000000..12bd06b3 --- /dev/null +++ b/plugins/dumbloop/uwsgiplugin.py @@ -0,0 +1,6 @@ +NAME='dumbloop' +CFLAGS = [] +LDFLAGS = [] +LIBS = [] + +GCC_LIST = ['dumb'] diff --git a/plugins/gevent/gevent.c b/plugins/gevent/gevent.c index d8b86e40..a5595f87 100644 --- a/plugins/gevent/gevent.c +++ b/plugins/gevent/gevent.c @@ -326,10 +326,6 @@ 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/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index b12c8ce7..0ca3d6a8 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -1329,6 +1329,7 @@ int uwsgi_check_python_mtime(PyObject *times_dict, char *filename) { } PyObject *uwsgi_python_setup_thread(char *name) { + // block signals on this thread sigset_t smask; sigfillset(&smask);