diff --git a/master.c b/master.c index 29da8b1f..653e419b 100644 --- a/master.c +++ b/master.c @@ -317,11 +317,13 @@ int master_loop(char **argv, char **environ) { 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) { + struct uwsgi_spooler *uspool = uwsgi.spoolers; + while(uspool) { #ifdef UWSGI_DEBUG - uwsgi_log("adding %d to signal poll (spooler)\n", uwsgi.shared->spooler_signal_pipe[0]); + uwsgi_log("adding %d to signal poll (spooler)\n", uspool->signal_pipe[0]); #endif - event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]); + event_queue_add_fd_read(uwsgi.master_queue, uspool->signal_pipe[0]); + uspool = uspool->next; } #endif @@ -786,7 +788,7 @@ int master_loop(char **argv, char **environ) { master_has_children = 1; } #ifdef UWSGI_SPOOLER - if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { + if (uwsgi.spoolers) { master_has_children = 1; } #endif @@ -1195,7 +1197,7 @@ int master_loop(char **argv, char **environ) { #ifdef UWSGI_SPOOLER // check for spooler signal - if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { + if (uwsgi.spoolers) { if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) { rlen = read(interesting_fd, &uwsgi_signal, 1); if (rlen < 0) { @@ -1213,6 +1215,28 @@ int master_loop(char **argv, char **environ) { } goto health_cycle; } + + struct uwsgi_spooler *uspool = uwsgi.spoolers; + while(uspool) { + if (interesting_fd == uspool->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); + } + goto health_cycle; + } + uspool = uspool->next; + } } #endif @@ -1444,12 +1468,14 @@ int master_loop(char **argv, char **environ) { } } #ifdef UWSGI_SPOOLER - if (uwsgi.shared->spooler_pid > 0 && uwsgi.shared->spooler_harakiri > 0) { - if (uwsgi.shared->spooler_harakiri < (time_t) uwsgi.current_time) { - uwsgi_log("*** HARAKIRI ON THE SPOOLER (pid: %d) ***\n", uwsgi.shared->spooler_pid); - kill(uwsgi.shared->spooler_pid, SIGKILL); - uwsgi.shared->spooler_harakiri = 0; + struct uwsgi_spooler *uspool = uwsgi.spoolers; + while(uspool) { + if (uspool->harakiri > 0 && uspool->harakiri < (time_t) uwsgi.current_time) { + uwsgi_log("*** HARAKIRI ON THE SPOOLER (pid: %d) ***\n", uspool->pid); + kill(uspool->pid, SIGKILL); + uspool->harakiri = 0; } + uspool = uspool->next; } #endif @@ -1522,15 +1548,21 @@ int master_loop(char **argv, char **environ) { #ifdef UWSGI_SPOOLER /* reload the spooler */ - if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { - if (diedpid == uwsgi.shared->spooler_pid) { + struct uwsgi_spooler *uspool = uwsgi.spoolers; + pid_found = 0; + while(uspool) { + if (uspool->pid > 0 && diedpid == uspool->pid) { uwsgi_log("OOOPS the spooler is no more...trying respawn...\n"); - uwsgi.spooler_respawned++; - uwsgi.shared->spooler_pid = spooler_start(); - //event_queue_add_fd_read(uwsgi.master_queue, uwsgi.shared->spooler_signal_pipe[0]); - continue; + uspool->respawned++; + uspool->pid = spooler_start(uspool); + pid_found = 1; + break; } + uspool = uspool->next; } + + if (pid_found) + continue; #endif pid_found = 0; @@ -1593,11 +1625,13 @@ int master_loop(char **argv, char **environ) { if (uwsgi.mywid <= 0) { // check spooler, mules, gateways and daemons #ifdef UWSGI_SPOOLER - if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { - if (diedpid == uwsgi.shared->spooler_pid) { + struct uwsgi_spooler *uspool = uwsgi.spoolers; + while(uspool) { + if (uspool->pid > 0 && diedpid == uspool->pid) { uwsgi_log("spooler (pid: %d) annihilated\n", (int) diedpid); goto next; } + uspool = uspool->next; } #endif diff --git a/master_utils.c b/master_utils.c index 3b835284..7edba5b3 100644 --- a/master_utils.c +++ b/master_utils.c @@ -52,7 +52,7 @@ void uwsgi_fixup_fds(int wid, int muleid) { } } #ifdef UWSGI_SPOOLER - if (uwsgi.shared->spooler_pid != getpid()) { + if (uwsgi.i_am_a_spooler && uwsgi.i_am_a_spooler->pid != getpid()) { if (uwsgi.shared->spooler_signal_pipe[0] != -1) close (uwsgi.shared->spooler_signal_pipe[0]); if (uwsgi.shared->spooler_signal_pipe[1] != -1) close (uwsgi.shared->spooler_signal_pipe[1]); } diff --git a/plugins/python/python_plugin.c b/plugins/python/python_plugin.c index 878ea466..c8f5a342 100644 --- a/plugins/python/python_plugin.c +++ b/plugins/python/python_plugin.c @@ -210,10 +210,8 @@ void uwsgi_python_atexit() { void uwsgi_python_post_fork() { #ifdef UWSGI_SPOOLER - if (uwsgi.shared->spooler_pid > 0) { - if (uwsgi.shared->spooler_pid == getpid()) { - UWSGI_GET_GIL - } + if (uwsgi.i_am_a_spooler) { + UWSGI_GET_GIL } #endif @@ -665,7 +663,7 @@ void init_uwsgi_embedded_module() { init_uwsgi_module_advanced(new_uwsgi_module); #ifdef UWSGI_SPOOLER - if (uwsgi.spool_dir != NULL) { + if (uwsgi.spoolers) { init_uwsgi_module_spooler(new_uwsgi_module); } #endif diff --git a/plugins/python/uwsgi_pymodule.c b/plugins/python/uwsgi_pymodule.c index bb8a9e1b..18558271 100644 --- a/plugins/python/uwsgi_pymodule.c +++ b/plugins/python/uwsgi_pymodule.c @@ -884,7 +884,7 @@ PyObject *py_uwsgi_log(PyObject * self, PyObject * args) { PyObject *py_uwsgi_i_am_the_spooler(PyObject * self, PyObject * args) { #ifdef UWSGI_SPOOLER - if (uwsgi.mypid == uwsgi.shared->spooler_pid) { + if (uwsgi.i_am_a_spooler) { Py_INCREF(Py_True); return Py_True; } @@ -900,7 +900,7 @@ PyObject *py_uwsgi_lock(PyObject * self, PyObject * args) { // the spooler cannot lock resources #ifdef UWSGI_SPOOLER - if (uwsgi.mypid == uwsgi.shared->spooler_pid) { + if (uwsgi.i_am_a_spooler) { return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources"); } #endif @@ -924,7 +924,7 @@ PyObject *py_uwsgi_unlock(PyObject * self, PyObject * args) { int lock_num = 0; #ifdef UWSGI_SPOOLER - if (uwsgi.mypid == uwsgi.shared->spooler_pid) { + if (uwsgi.i_am_a_spooler) { return PyErr_Format(PyExc_ValueError, "The spooler cannot lock/unlock resources"); } #endif @@ -1452,23 +1452,25 @@ PyObject *py_uwsgi_spooler_jobs(PyObject * self, PyObject * args) { PyObject *jobslist = PyList_New(0); - sdir = opendir(uwsgi.spool_dir); + struct uwsgi_spooler *uspool = uwsgi.spoolers; + + sdir = opendir(uspool->dir); if (sdir) { while ((dp = readdir(sdir)) != NULL) { if (!strncmp("uwsgi_spoolfile_on_", dp->d_name, 19)) { - abs_path = malloc(strlen(uwsgi.spool_dir) + 1 + strlen(dp->d_name) + 1); + abs_path = malloc(strlen(uspool->dir) + 1 + strlen(dp->d_name) + 1); if (!abs_path) { uwsgi_error("malloc()"); closedir(sdir); goto clear; } - memset(abs_path, 0, strlen(uwsgi.spool_dir) + 1 + strlen(dp->d_name) + 1); + memset(abs_path, 0, strlen(uspool->dir) + 1 + strlen(dp->d_name) + 1); - memcpy(abs_path, uwsgi.spool_dir, strlen(uwsgi.spool_dir)); - memcpy(abs_path + strlen(uwsgi.spool_dir), "/", 1); - memcpy(abs_path + strlen(uwsgi.spool_dir) + 1, dp->d_name, strlen(dp->d_name)); + memcpy(abs_path, uspool->dir, strlen(uspool->dir)); + memcpy(abs_path + strlen(uspool->dir), "/", 1); + memcpy(abs_path + strlen(uspool->dir) + 1, dp->d_name, strlen(dp->d_name)); if (lstat(abs_path, &sf_lstat)) { @@ -1631,7 +1633,7 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) { if (numprio) { priority = uwsgi_num2str(numprio); } - i = spool_request(spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, spool_buffer, cur_buf - spool_buffer, priority, at, body, body_len); + i = spool_request(uwsgi.spoolers, spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, spool_buffer, cur_buf - spool_buffer, priority, at, body, body_len); if (priority) { free(priority); } @@ -1651,7 +1653,9 @@ PyObject *py_uwsgi_send_spool(PyObject * self, PyObject * args, PyObject *kw) { } PyObject *py_uwsgi_spooler_pid(PyObject * self, PyObject * args) { - return PyInt_FromLong(uwsgi.shared->spooler_pid ? uwsgi.shared->spooler_pid : 0); + struct uwsgi_spooler *uspool = uwsgi.spoolers; + if (!uwsgi.spoolers) return PyInt_FromLong(0); + return PyInt_FromLong(uspool->pid); } #endif diff --git a/signal.c b/signal.c index fc267802..7c53300c 100644 --- a/signal.c +++ b/signal.c @@ -53,7 +53,7 @@ int uwsgi_signal_handler(uint8_t sig) { } } #ifdef UWSGI_SPOOLER - else if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0 && (getpid() == uwsgi.shared->spooler_pid)) { + else if (uwsgi.i_am_a_spooler && (getpid() == uwsgi.i_am_a_spooler->pid)) { if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) { set_spooler_harakiri(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI]); } @@ -75,7 +75,7 @@ int uwsgi_signal_handler(uint8_t sig) { } } #ifdef UWSGI_SPOOLER - else if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0 && (getpid() == uwsgi.shared->spooler_pid)) { + else if (uwsgi.i_am_a_spooler && (getpid() == uwsgi.i_am_a_spooler->pid)) { if(uwsgi.shared->options[UWSGI_OPTION_SPOOLER_HARAKIRI] > 0) { set_spooler_harakiri(0); } diff --git a/spooler.c b/spooler.c index fac6a1a3..9a8bd52e 100644 --- a/spooler.c +++ b/spooler.c @@ -12,7 +12,7 @@ void spooler_manage_task(char *, char *); // fake function to allow waking the spooler void spooler_wakeup() {} -pid_t spooler_start() { +pid_t spooler_start(struct uwsgi_spooler *uspool) { int i; @@ -26,8 +26,9 @@ pid_t spooler_start() { signal(SIGUSR1, spooler_wakeup); uwsgi.mywid = -1; uwsgi.mypid = getpid(); + uspool->pid = uwsgi.mypid; // avoid race conditions !!! - uwsgi.shared->spooler_pid = uwsgi.mypid; + uwsgi.i_am_a_spooler = uspool; uwsgi_fixup_fds(0, 0); uwsgi_close_all_sockets(); @@ -52,10 +53,10 @@ pid_t spooler_start() { } } - spooler(); + spooler(uspool); } else if (pid > 0) { - uwsgi_log("spawned the uWSGI spooler on dir %s with pid %d\n", uwsgi.spool_dir, pid); + uwsgi_log("spawned the uWSGI spooler on dir %s with pid %d\n", uspool->dir, pid); } return pid; @@ -78,32 +79,36 @@ void destroy_spool(char *dir, char *file) { } -int spool_request(char *filename, int rn, int core_id, char *buffer, int size, char *priority, time_t at, char *body, size_t body_len) { +int spool_request(struct uwsgi_spooler *uspool, char *filename, int rn, int core_id, char *buffer, int size, char *priority, time_t at, char *body, size_t body_len) { struct timeval tv; int fd; struct uwsgi_header uh; - uwsgi_lock(uwsgi.spooler_lock); + if (!uspool) { + uspool = uwsgi.spoolers; + } + + uwsgi_lock(uspool->lock); gettimeofday(&tv, NULL); if (priority) { - if (snprintf(filename, 1024, "%s/%s", uwsgi.spool_dir, priority) <= 0) { - uwsgi_unlock(uwsgi.spooler_lock); + if (snprintf(filename, 1024, "%s/%s", uspool->dir, priority) <= 0) { + uwsgi_unlock(uspool->lock); return 0; } // no need to check for errors... (void) mkdir(filename, 0777); - if (snprintf(filename, 1024, "%s/%s/uwsgi_spoolfile_on_%s_%d_%d_%d_%llu_%llu", uwsgi.spool_dir, priority, uwsgi.hostname, (int) getpid(), rn, core_id, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) { - uwsgi_unlock(uwsgi.spooler_lock); + if (snprintf(filename, 1024, "%s/%s/uwsgi_spoolfile_on_%s_%d_%d_%d_%llu_%llu", uspool->dir, priority, uwsgi.hostname, (int) getpid(), rn, core_id, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) { + uwsgi_unlock(uspool->lock); return 0; } } else { - if (snprintf(filename, 1024, "%s/uwsgi_spoolfile_on_%s_%d_%d_%d_%llu_%llu", uwsgi.spool_dir, uwsgi.hostname, (int) getpid(), rn, core_id, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) { - uwsgi_unlock(uwsgi.spooler_lock); + if (snprintf(filename, 1024, "%s/uwsgi_spoolfile_on_%s_%d_%d_%d_%llu_%llu", uspool->dir, uwsgi.hostname, (int) getpid(), rn, core_id, (unsigned long long) tv.tv_sec, (unsigned long long) tv.tv_usec) <= 0) { + uwsgi_unlock(uspool->lock); return 0; } } @@ -111,7 +116,7 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size, c fd = open(filename, O_CREAT | O_EXCL | O_WRONLY, S_IRUSR | S_IWUSR); if (fd < 0) { uwsgi_error_open(filename); - uwsgi_unlock(uwsgi.spooler_lock); + uwsgi_unlock(uspool->lock); return 0; } @@ -123,7 +128,7 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size, c uwsgi_error("flock()"); #endif close(fd); - uwsgi_unlock(uwsgi.spooler_lock); + uwsgi_unlock(uspool->lock); return 0; } @@ -167,18 +172,18 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size, c uwsgi_log("[spooler] written %d bytes to file %s\n", size + body_len + 4, filename); - uwsgi_unlock(uwsgi.spooler_lock); + uwsgi_unlock(uspool->lock); /* wake up the spooler ... (HACKY) */ - if (uwsgi.shared->spooler_pid > 0 ) { - (void) kill(uwsgi.shared->spooler_pid, SIGUSR1); + if (uspool->pid > 0 ) { + (void) kill(uspool->pid, SIGUSR1); } return 1; clear: - uwsgi_unlock(uwsgi.spooler_lock); + uwsgi_unlock(uspool->lock); uwsgi_error("write()"); if (unlink(filename)) { uwsgi_error("unlink()"); @@ -189,7 +194,7 @@ int spool_request(char *filename, int rn, int core_id, char *buffer, int size, c -void spooler() { +void spooler(struct uwsgi_spooler *uspool) { // prevent process blindly reading stdin to make mess int nullfd; @@ -228,20 +233,20 @@ void spooler() { for (;;) { - if (chdir(uwsgi.spool_dir)) { + if (chdir(uspool->dir)) { uwsgi_error("chdir()"); exit(1); } if (uwsgi.spooler_ordered) { #ifdef __linux__ - spooler_scandir(uwsgi.spool_dir); + spooler_scandir(uspool->dir); #else - spooler_readdir(uwsgi.spool_dir); + spooler_readdir(uspool->dir); #endif } else { - spooler_readdir(uwsgi.spool_dir); + spooler_readdir(uspool->dir); } if (event_queue_wait(spooler_event_queue, uwsgi.shared->spooler_frequency, &interesting_fd) > 0) { @@ -447,13 +452,17 @@ int uwsgi_request_spooler(struct wsgi_request *wsgi_req) { int i; char spool_filename[1024]; - if (uwsgi.spool_dir == NULL) { + // get the spooler from the modifier2 + + struct uwsgi_spooler *uspool = uwsgi.spoolers; + + if (uspool == NULL) { uwsgi_log("the spooler is inactive !!!...skip\n"); uwsgi_send_empty_pkt(wsgi_req->poll.fd, NULL, 255, 0); return -1; } - i = spool_request(spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, wsgi_req->buffer, wsgi_req->uh.pktsize, NULL, 0, NULL, 0); + i = spool_request(uspool, spool_filename, uwsgi.workers[0].requests + 1, wsgi_req->async_id, wsgi_req->buffer, wsgi_req->uh.pktsize, NULL, 0, NULL, 0); wsgi_req->uh.modifier1 = 255; wsgi_req->uh.pktsize = 0; if (i > 0) { diff --git a/utils.c b/utils.c index 60219f17..841c0bc5 100644 --- a/utils.c +++ b/utils.c @@ -125,10 +125,10 @@ void set_mule_harakiri(int sec) { #ifdef UWSGI_SPOOLER void set_spooler_harakiri(int sec) { if (sec == 0) { - uwsgi.shared->spooler_harakiri = 0; + uwsgi.i_am_a_spooler->harakiri = 0; } else { - uwsgi.shared->spooler_harakiri = time(NULL) + sec; + uwsgi.i_am_a_spooler->harakiri = time(NULL) + sec; } if (!uwsgi.master_process) { alarm(sec); @@ -2754,6 +2754,51 @@ void uwsgi_dyn_dict_del(struct uwsgi_dyn_dict *item) { free(item); } +void *uwsgi_malloc_shared(size_t size) { + + void *addr = mmap(NULL, size, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0); + + if (addr == NULL) { + uwsgi_error("mmap()"); + exit(1); + } + + return addr; +} + + +struct uwsgi_spooler *uwsgi_new_spooler(char *dir) { + + struct uwsgi_spooler *uspool = uwsgi.spoolers; + + if (!uspool) { + uwsgi.spoolers = uwsgi_malloc_shared(sizeof(struct uwsgi_spooler)); + uspool = uwsgi.spoolers; + } + else { + while(uspool) { + if (uspool->next == NULL) { + uspool->next = uwsgi_malloc_shared(sizeof(struct uwsgi_spooler)); + uspool = uspool->next; + break; + } + uspool = uspool->next; + } + } + + if (!realpath(dir, uspool->dir)) { + uwsgi_error("[spooler] realpath()"); + exit(1); + } + + uspool->lock = uwsgi_mmap_shared_lock(); + uwsgi_lock_init(uspool->lock); + + uspool->next = NULL; + + return uspool; +} + struct uwsgi_string_list *uwsgi_string_new_list(struct uwsgi_string_list **list, char *value) { diff --git a/uwsgi.c b/uwsgi.c index c3d242ec..9eca9eab 100644 --- a/uwsgi.c +++ b/uwsgi.c @@ -616,6 +616,19 @@ void goodbye_cruel_world() { exit(0); } +static void uwsgi_signal_spoolers(int signum) { + + struct uwsgi_spooler *uspool = uwsgi.spoolers; + while(uspool) { + if (uspool->pid > 0) { + kill(uspool->pid, SIGKILL); + uwsgi_log("killing the spooler with pid %d\n", uspool->pid); + } + uspool = uspool->next; + } + +} + void kill_them_all(int signum) { int i; uwsgi.to_hell = 1; @@ -643,11 +656,7 @@ void kill_them_all(int signum) { } #ifdef UWSGI_SPOOLER - if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { - kill(uwsgi.shared->spooler_pid, SIGKILL); - uwsgi_log("killing the spooler with pid %d\n", uwsgi.shared->spooler_pid); - } - + uwsgi_signal_spoolers(SIGKILL); #endif if (uwsgi.emperor_pid >= 0) { @@ -695,10 +704,7 @@ void grace_them_all(int signum) { } #ifdef UWSGI_SPOOLER - if (uwsgi.spool_dir && uwsgi.shared->spooler_pid > 0) { - kill(uwsgi.shared->spooler_pid, SIGKILL); - uwsgi_log("killing the spooler with pid %d\n", uwsgi.shared->spooler_pid); - } + uwsgi_signal_spoolers(SIGKILL); #endif if (uwsgi.emperor_pid >= 0) { @@ -1974,13 +1980,6 @@ int uwsgi_start(void *v_argv) { uwsgi_lock_init(uwsgi.cron_table_lock); } -#ifdef UWSGI_SPOOLER - if (uwsgi.spool_dir) { - // spooler lock - uwsgi.spooler_lock = uwsgi_mmap_shared_lock(); - uwsgi_lock_init(uwsgi.spooler_lock); - } -#endif uwsgi.rpc_table_lock = uwsgi_mmap_shared_lock(); uwsgi_lock_init(uwsgi.rpc_table_lock); @@ -2486,25 +2485,6 @@ skipzero: } - /* - - uwsgi.shared->hooks[0] = uwsgi_request_wsgi; - uwsgi.shared->after_hooks[0] = uwsgi_after_request_wsgi; - - uwsgi.shared->hooks[UWSGI_MODIFIER_ADMIN_REQUEST] = uwsgi_request_admin; //10 - #ifdef UWSGI_SPOOLER - uwsgi.shared->hooks[UWSGI_MODIFIER_SPOOL_REQUEST] = uwsgi_request_spooler; //17 - #endif - uwsgi.shared->hooks[UWSGI_MODIFIER_EVAL] = uwsgi_request_eval; //22 - uwsgi.shared->hooks[UWSGI_MODIFIER_FASTFUNC] = uwsgi_request_fastfunc; //26 - - uwsgi.shared->hooks[UWSGI_MODIFIER_MANAGE_PATH_INFO] = uwsgi_request_wsgi; // 30 - uwsgi.shared->after_hooks[UWSGI_MODIFIER_MANAGE_PATH_INFO] = uwsgi_after_request_wsgi; // 30 - - uwsgi.shared->hooks[UWSGI_MODIFIER_MESSAGE_MARSHAL] = uwsgi_request_marshal; //33 - uwsgi.shared->hooks[UWSGI_MODIFIER_PING] = uwsgi_request_ping; //100 - */ - if (!uwsgi.numproc) { uwsgi_log("*** Operational MODE: no-workers ***\n"); } @@ -2613,9 +2593,14 @@ skipzero: #ifdef UWSGI_SPOOLER - if (uwsgi.spool_dir != NULL && uwsgi.sockets) { + if (uwsgi.spoolers != NULL && uwsgi.sockets) { create_signal_pipe(uwsgi.shared->spooler_signal_pipe); - uwsgi.shared->spooler_pid = spooler_start(); + struct uwsgi_spooler *uspool = uwsgi.spoolers; + while(uspool) { + create_signal_pipe(uspool->signal_pipe); + uspool->pid = spooler_start(uspool); + uspool = uspool->next; + } } #endif @@ -3735,15 +3720,11 @@ static int manage_base_opt(int i, char *optarg) { #endif #ifdef UWSGI_SPOOLER case 'Q': - uwsgi.spool_dir = uwsgi_malloc(PATH_MAX); if (access(optarg, R_OK | W_OK | X_OK)) { uwsgi_error("[spooler directory] access()"); exit(1); } - if (!realpath(optarg, uwsgi.spool_dir)) { - uwsgi_error("realpath()"); - exit(1); - } + uwsgi_new_spooler(optarg); uwsgi.master_process = 1; return 1; #endif diff --git a/uwsgi.h b/uwsgi.h index bb1bfc4a..0163c1b8 100644 --- a/uwsgi.h +++ b/uwsgi.h @@ -772,6 +772,18 @@ struct uwsgi_app { uint64_t avg_response_time; }; +struct uwsgi_spooler { + + char dir[PATH_MAX]; + pid_t pid; + uint64_t respawned; + void *lock; + time_t harakiri; + + int signal_pipe[2]; + + struct uwsgi_spooler *next; +}; #ifdef UWSGI_ROUTING struct uwsgi_route { @@ -1298,10 +1310,10 @@ struct uwsgi_server { #endif #ifdef UWSGI_SPOOLER - char *spool_dir; + struct uwsgi_spooler *spoolers; + struct uwsgi_spooler *i_am_a_spooler; char *spooler_chdir; int spooler_ordered; - uint64_t spooler_respawned; #endif #ifdef UWSGI_SNMP @@ -1580,9 +1592,6 @@ struct uwsgi_server { void *cron_table_lock; void *rpc_table_lock; void *sa_lock; -#ifdef UWSGI_SPOOLER - void *spooler_lock; -#endif // subscription client int subscribe_freq; @@ -1695,12 +1704,6 @@ struct uwsgi_shared { off_t logsize; -#ifdef UWSGI_SPOOLER - pid_t spooler_pid; - int spooler_frequency; - time_t spooler_harakiri; -#endif - #ifdef UWSGI_SNMP char snmp_community[72 + 1]; struct uwsgi_snmp_server_value snmp_gvalue[100]; @@ -1718,6 +1721,7 @@ struct uwsgi_shared { int worker_signal_pipe[2]; #ifdef UWSGI_SPOOLER + int spooler_frequency; int spooler_signal_pipe[2]; #endif int mule_signal_pipe[2]; @@ -1910,9 +1914,9 @@ void snmp_init(void); #endif #ifdef UWSGI_SPOOLER -int spool_request(char *, int, int, char *, int, char *, time_t, char *, size_t); -void spooler(void); -pid_t spooler_start(void); +int spool_request(struct uwsgi_spooler *uspool, char *, int, int, char *, int, char *, time_t, char *, size_t); +void spooler(struct uwsgi_spooler *); +pid_t spooler_start(struct uwsgi_spooler *); #endif void set_harakiri(int); @@ -2582,6 +2586,10 @@ char *uwsgi_get_var(struct wsgi_request *, char *, uint16_t, uint16_t *); void escape_shell_arg(char *, size_t, char *); +void *uwsgi_malloc_shared(size_t); + +struct uwsgi_spooler *uwsgi_new_spooler(char *); + #ifdef UWSGI_AS_SHARED_LIBRARY int uwsgi_init(int, char **, char **); #endif