diff --git a/decoratortest.py b/decoratortest.py index d22b5dd4..61bb741c 100644 --- a/decoratortest.py +++ b/decoratortest.py @@ -10,8 +10,8 @@ import time # register rpc function helloworld @rpc("helloworld") -def hello_world(): - return "Hello World" +def hello2(): + return "[RPC] Hello World" # register signal 1 @signal(1) @@ -45,6 +45,7 @@ def tmpmodified(num): def a_long_task(args): for i in xrange(1,10): print("%s = %d" % ( str(args), i)) + print(uwsgi.call('helloworld')) time.sleep(1) # continuosly spool a long running task @@ -52,10 +53,11 @@ def a_long_task(args): def an_infinite_task(args): for i in xrange(1,4): print("infinite: %d %s" % (i, str(args))) + print(uwsgi.call('helloworld')) time.sleep(1) -# spool a task after 60 seconds +# spool a task after 5 seconds @spool def delayed_task(args): print("*** I am a delayed spool job. It is %s [%s]***" % (time.asctime(), str(args))) @@ -89,7 +91,10 @@ def a_running_thread_with_args(who): def a_post_fork_thread(): while True: time.sleep(3) - print("Hello from a thread in worker %d" % uwsgi.worker_id()) + if uwsgi.i_am_the_spooler(): + print("Hello from a thread in the spooler") + else: + print("Hello from a thread in worker %d" % uwsgi.worker_id()) @postfork def fork_happened(): @@ -97,24 +102,29 @@ def fork_happened(): @postfork def fork_happened2(): - print("waiting for a signal...") - uwsgi.signal_wait() - print("signal received: %d" % uwsgi.signal_received()) + if uwsgi.i_am_the_spooler(): + return + print("worker %d is waiting for signal 100..." % uwsgi.worker_id()) + uwsgi.signal_wait(100) + print("worker %d received signal %d" % (uwsgi.worker_id(), uwsgi.signal_received())) print("fork() has been called [2] wid: %d" % uwsgi.worker_id()) @postfork @lock def locked_func(): print("starting locked function on worker %d" % uwsgi.worker_id()) - for i in xrange(1, 100): - time.sleep(0.2) + for i in xrange(1, 5): + time.sleep(1) print("[locked %d] waiting..." % uwsgi.worker_id()) print("done with locked function on worker %d" % uwsgi.worker_id()) +print(uwsgi.call('helloworld')) spool_filename = a_long_task.spool({'foo':'bar'}, hello='world') print("spool filename = %s" % spool_filename) an_infinite_task.spool(foo='bar', priority=3) -delayed_task.spool(foo2='bar2', at=time.time()+60) +when = int(time.time())+5 +print("scheduling a delayed task at %d" % when) +delayed_task.spool(foo2='bar2', at=when) a_running_thread() a_running_thread_with_args("uWSGI") uwsgi_source_file = open('uwsgi.c','r') diff --git a/lock.c b/lock.c index 4fcd92a0..42b7eafd 100644 --- a/lock.c +++ b/lock.c @@ -46,6 +46,7 @@ void uwsgi_lock(void *lock) { void uwsgi_unlock(void *lock) { pthread_mutex_unlock((pthread_mutex_t *) lock + sizeof(pthread_mutexattr_t)); + } void uwsgi_rwlock_init(void *lock) { diff --git a/master.c b/master.c index 3b4fd608..71271971 100644 --- a/master.c +++ b/master.c @@ -318,6 +318,15 @@ void master_loop(char **argv, char **environ) { #endif event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->worker_signal_pipe[0]); +#ifdef UWSGI_SPOOLER + if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { +#ifdef UWSGI_DEBUG + uwsgi_log("adding %d to signal poll (spooler)\n", uwsgi.shared->spooler_signal_pipe[0]); +#endif + event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]); + } +#endif + if (uwsgi.log_master) { #ifdef UWSGI_DEBUG uwsgi_log("adding %d to master logging\n", uwsgi.shared->worker_log_pipe[0]); @@ -1016,6 +1025,30 @@ void master_loop(char **argv, char **environ) { //uwsgi.workers[i].pipe[0] = -1; } } + +#ifdef UWSGI_SPOOLER + // check for spooler signal + if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { + if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) { + rlen = read(interesting_fd, &uwsgi_signal, 1); + if (rlen < 0) { + uwsgi_error("read()"); + } + else if (rlen > 0) { +#ifdef UWSGI_DEBUG + uwsgi_log_verbose("received uwsgi signal %d from the spooler\n", uwsgi_signal); +#endif + uwsgi_route_signal(uwsgi_signal); + } + else { + uwsgi_log_verbose("lost connection with the spooler\n"); + close(interesting_fd); + } + } + } +#endif + + } uwsgi.current_time = time(NULL); diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index ab8b4d8b..b1e26dd9 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -29,6 +29,9 @@ PyObject *py_uwsgi_signal_wait(PyObject * self, PyObject * args) { } else { #endif + + UWSGI_RELEASE_GIL; + pfd[0].fd = uwsgi.signal_socket; pfd[0].events = POLLIN; pfd[1].fd = uwsgi.my_signal_socket; @@ -55,6 +58,7 @@ cycle: uwsgi_error("read()"); } else { + if (uwsgi_signal_handler(received_signal)) { uwsgi_log_verbose("error managing signal %d on worker %d\n", received_signal, uwsgi.mywid); } @@ -64,8 +68,11 @@ cycle: } } } + } + UWSGI_GET_GIL; + #ifdef UWSGI_ASYNC } #endif @@ -961,6 +968,18 @@ PyObject *py_uwsgi_log(PyObject * self, PyObject * args) { return Py_True; } +PyObject *py_uwsgi_i_am_the_spooler(PyObject * self, PyObject * args) { +#ifdef UWSGI_SPOOLER + if (uwsgi.mypid == uwsgi.shared->spooler_pid) { + Py_INCREF(Py_True); + return Py_True; + } +#endif + + Py_INCREF(Py_None); + return Py_None; +} + PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) { // the spooler cannot lock resources @@ -2684,6 +2703,7 @@ static PyMethodDef uwsgi_advanced_methods[] = { {"recv_block", py_uwsgi_recv_block, METH_VARARGS, ""}, {"recv_frame", py_uwsgi_recv_frame, METH_VARARGS, ""}, {"close", py_uwsgi_close, METH_VARARGS, ""}, + {"i_am_the_spooler", py_uwsgi_i_am_the_spooler, METH_VARARGS, ""}, {"fcgi", py_uwsgi_fcgi, METH_VARARGS, ""}, diff --git a/spooler.c b/spooler.c index 65bb62ff..026252d6 100644 --- a/spooler.c +++ b/spooler.c @@ -36,7 +36,7 @@ pid_t spooler_start() { // USR1 will be used to wake up the spooler signal(SIGUSR1, spooler_wakeup); uwsgi.mywid = -1; - uwsgi.mypid = pid; + uwsgi.mypid = getpid(); uwsgi_close_all_sockets(); if (uwsgi.master_process) { close(uwsgi.shared->spooler_signal_pipe[0]); @@ -52,7 +52,9 @@ pid_t spooler_start() { uwsgi.p[i]->post_fork(); } } + uwsgi.signal_socket = uwsgi.shared->spooler_signal_pipe[1]; + for (i = 0; i < 0xFF; i++) { if (uwsgi.p[i]->spooler_init) { uwsgi.p[i]->spooler_init(); diff --git a/uwsgidecorators.py b/uwsgidecorators.py index d4464367..e0aebf0d 100644 --- a/uwsgidecorators.py +++ b/uwsgidecorators.py @@ -153,6 +153,9 @@ class lock(object): self.f = f def __call__(self, *args, **kwargs): + # ensure the spooler will not call it + if uwsgi.i_am_the_spooler(): + return uwsgi.lock() try: return self.f(*args, **kwargs)