int uwsgi_signal_wait(int signum) { int wait_for_specific_signal = 0; uint8_t uwsgi_signal = 0; int received_signal = -1; int ret; struct pollfd pfd[2]; if (signum > -1) { wait_for_specific_signal = 1; } pfd[0].fd = uwsgi.signal_socket; pfd[0].events = POLLIN; pfd[1].fd = uwsgi.my_signal_socket; pfd[1].events = POLLIN; cycle: ret = poll(pfd, 2, -1); if (ret > 0) { if (pfd[0].revents == POLLIN) { if (read(uwsgi.signal_socket, &uwsgi_signal, 1) != 1) { uwsgi_error("read()"); } else { (void) uwsgi_signal_handler(uwsgi_signal); if (wait_for_specific_signal) { if (signum != uwsgi_signal) goto cycle; } received_signal = uwsgi_signal; } } if (pfd[1].revents == POLLIN) { if (read(uwsgi.my_signal_socket, &uwsgi_signal, 1) != 1) { uwsgi_error("read()"); } else { (void) uwsgi_signal_handler(uwsgi_signal); if (wait_for_specific_signal) { if (signum != uwsgi_signal) goto cycle; } } received_signal = uwsgi_signal; } } return received_signal; }
void uwsgi_receive_signal(int fd, char *name, int id) { uint8_t uwsgi_signal; ssize_t ret = read(fd, &uwsgi_signal, 1); if (ret == 0) { goto destroy; } else if (ret < 0 && errno != EAGAIN && errno != EWOULDBLOCK) { uwsgi_error("[uwsgi-signal] read()"); goto destroy; } else if (ret > 0) { #ifdef UWSGI_DEBUG uwsgi_log_verbose("master sent signal %d to %s %d\n", uwsgi_signal, name, id); #endif if (uwsgi_signal_handler(uwsgi_signal)) { uwsgi_log_verbose("error managing signal %d on %s %d\n", uwsgi_signal, name, id); } } return; destroy: // better to kill the whole worker... uwsgi_log_verbose("uWSGI %s %d screams: UAAAAAAH my master disconnected: i will kill myself !!!\n", name, id); end_me(0); }
void uwsgi_mule_handler() { ssize_t len; uint8_t uwsgi_signal; int rlen; int interesting_fd; // this must be configurable char message[65536]; int mule_queue = event_queue_init(); event_queue_add_fd_read(mule_queue, uwsgi.signal_socket); event_queue_add_fd_read(mule_queue, uwsgi.my_signal_socket); event_queue_add_fd_read(mule_queue, uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1]); event_queue_add_fd_read(mule_queue, uwsgi.shared->mule_queue_pipe[1]); uwsgi_mule_add_farm_to_queue(mule_queue); for (;;) { rlen = event_queue_wait(mule_queue, -1, &interesting_fd); if (rlen <= 0) { continue; } if (interesting_fd == uwsgi.signal_socket || interesting_fd == uwsgi.my_signal_socket || farm_has_signaled(interesting_fd)) { len = read(interesting_fd, &uwsgi_signal, 1); if (len <= 0) { uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid); end_me(0); } #ifdef UWSGI_DEBUG uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid); #endif if (uwsgi_signal_handler(uwsgi_signal)) { uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.muleid); } } else if (interesting_fd == uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1] || interesting_fd == uwsgi.shared->mule_queue_pipe[1] || farm_has_msg(interesting_fd)) { len = read(interesting_fd, message, 65536); if (len < 0) { uwsgi_error("read()"); } else { int i, found = 0; for (i = 0; i < 256; i++) { if (uwsgi.p[i]->mule_msg) { if (uwsgi.p[i]->mule_msg(message, len)) { found = 1; break; } } } if (!found) uwsgi_log("*** mule %d received a %ld bytes message ***\n", uwsgi.muleid, (long) len); } } } }
PyObject *py_uwsgi_gevent_signal_handler(PyObject * self, PyObject * args) { uint8_t uwsgi_signal; int signal_socket; if (!PyArg_ParseTuple(args, "i:uwsgi_gevent_signal_handler", &signal_socket)) { return NULL; } if (read(signal_socket, &uwsgi_signal, 1) <= 0) { if (uwsgi.no_orphans) { uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid); end_me(0); } // close the socket to end the mess...from now on the worker is alone (no master) else close(signal_socket); } else { #ifdef UWSGI_DEBUG uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid); #endif if (uwsgi_signal_handler(uwsgi_signal)) { uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid); } } Py_INCREF(Py_None); return Py_None; }
ssize_t uwsgi_mule_get_msg(int manage_signals, int manage_farms, char *message, size_t buffer_size, int timeout) { ssize_t len = 0; struct pollfd *mulepoll; int count = 4; int farms_count = 0; uint8_t uwsgi_signal; int i; if (uwsgi.muleid == 0) return -1; if (manage_signals) count = 2; if (!manage_farms) goto next; for (i = 0; i < uwsgi.farms_cnt; i++) { if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) farms_count++; } next: if (timeout > -1) timeout = timeout * 1000; mulepoll = uwsgi_malloc(sizeof(struct pollfd) * (count + farms_count)); mulepoll[0].fd = uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1]; mulepoll[0].events = POLLIN; mulepoll[1].fd = uwsgi.shared->mule_queue_pipe[1]; mulepoll[1].events = POLLIN; if (count > 2) { mulepoll[2].fd = uwsgi.signal_socket; mulepoll[2].events = POLLIN; mulepoll[3].fd = uwsgi.my_signal_socket; mulepoll[3].events = POLLIN; } if (farms_count > 0) { int tmp_cnt = 0; for (i = 0; i < uwsgi.farms_cnt; i++) { if (uwsgi_farm_has_mule(&uwsgi.farms[i], uwsgi.muleid)) { mulepoll[count + tmp_cnt].fd = uwsgi.farms[i].queue_pipe[1]; mulepoll[count + tmp_cnt].events = POLLIN; tmp_cnt++; } } } int ret = poll(mulepoll, count + farms_count, timeout); if (ret <= 0) { uwsgi_error("poll"); } else { if (mulepoll[0].revents & POLLIN) { len = read(uwsgi.mules[uwsgi.muleid - 1].queue_pipe[1], message, buffer_size); } else if (mulepoll[1].revents & POLLIN) { len = read(uwsgi.shared->mule_queue_pipe[1], message, buffer_size); } else { if (count > 2) { int interesting_fd = -1; if (mulepoll[2].revents & POLLIN) { interesting_fd = mulepoll[2].fd; } else if (mulepoll[3].revents & POLLIN) { interesting_fd = mulepoll[3].fd; } if (interesting_fd > -1) { len = read(interesting_fd, &uwsgi_signal, 1); if (len <= 0) { uwsgi_log_verbose("uWSGI mule %d braying: my master died, i will follow him...\n", uwsgi.muleid); end_me(0); } #ifdef UWSGI_DEBUG uwsgi_log_verbose("master sent signal %d to mule %d\n", uwsgi_signal, uwsgi.muleid); #endif if (uwsgi_signal_handler(uwsgi_signal)) { uwsgi_log_verbose("error managing signal %d on mule %d\n", uwsgi_signal, uwsgi.mywid); } // set the error condition len = -1; goto clear; } } // read messages in the farm for (i = 0; i < farms_count; i++) { if (mulepoll[count + i].revents & POLLIN) { len = read(mulepoll[count + i].fd, message, buffer_size); break; } } } } if (len < 0) { uwsgi_error("read()"); goto clear; } clear: free(mulepoll); return len; }
void *zeromq_loop(void *arg1) { sigset_t smask; int i; long core_id = (long) arg1; struct wsgi_request *wsgi_req = uwsgi.wsgi_requests[core_id]; uwsgi.zeromq_recv_flag = 0; zmq_pollitem_t zmq_poll_items[3]; char uwsgi_signal; if (uwsgi.threads > 1) { pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &i); pthread_setcanceltype(PTHREAD_CANCEL_ASYNCHRONOUS, &i); pthread_setspecific(uwsgi.tur_key, (void *) wsgi_req); if (core_id > 0) { // block all signals on new threads sigfillset(&smask); pthread_sigmask(SIG_BLOCK, &smask, NULL); for (i = 0; i < 0xFF; i++) { if (uwsgi.p[i]->init_thread) { uwsgi.p[i]->init_thread(core_id); } } void *tmp_zmq_pull = zmq_socket(uwsgi.zmq_context, ZMQ_PULL); if (tmp_zmq_pull == NULL) { uwsgi_error("zmq_socket()"); exit(1); } if (zmq_connect(tmp_zmq_pull, uwsgi.zmq_receiver) < 0) { uwsgi_error("zmq_connect()"); exit(1); } pthread_setspecific(uwsgi.zmq_pull, tmp_zmq_pull); } } if (uwsgi.signal_socket > -1) { zmq_poll_items[0].socket = pthread_getspecific(uwsgi.zmq_pull); zmq_poll_items[0].fd = -1; zmq_poll_items[0].events = ZMQ_POLLIN; zmq_poll_items[1].socket = NULL; zmq_poll_items[1].fd = uwsgi.signal_socket; zmq_poll_items[1].events = ZMQ_POLLIN; zmq_poll_items[2].socket = NULL; zmq_poll_items[2].fd = uwsgi.my_signal_socket; zmq_poll_items[2].events = ZMQ_POLLIN; } while (uwsgi.workers[uwsgi.mywid].manage_next_request) { wsgi_req_setup(wsgi_req, core_id, NULL); uwsgi.edge_triggered = 1; wsgi_req->socket = uwsgi.zmq_socket; if (uwsgi.signal_socket > -1) { if (zmq_poll(zmq_poll_items, 3, -1) < 0) { uwsgi_error("zmq_poll()"); continue; } if (zmq_poll_items[1].revents & ZMQ_POLLIN) { if (read(uwsgi.signal_socket, &uwsgi_signal, 1) <= 0) { if (uwsgi.no_orphans) { uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid); end_me(0); } } else { #ifdef UWSGI_DEBUG uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid); #endif if (uwsgi_signal_handler(uwsgi_signal)) { uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid); } } continue; } if (zmq_poll_items[2].revents & ZMQ_POLLIN) { if (read(uwsgi.my_signal_socket, &uwsgi_signal, 1) <= 0) { if (uwsgi.no_orphans) { uwsgi_log_verbose("uWSGI worker %d screams: UAAAAAAH my master died, i will follow him...\n", uwsgi.mywid); end_me(0); } } else { #ifdef UWSGI_DEBUG uwsgi_log_verbose("master sent signal %d to worker %d\n", uwsgi_signal, uwsgi.mywid); #endif if (uwsgi_signal_handler(uwsgi_signal)) { uwsgi_log_verbose("error managing signal %d on worker %d\n", uwsgi_signal, uwsgi.mywid); } } continue; } if (zmq_poll_items[0].revents & ZMQ_POLLIN) { wsgi_req->poll.fd = wsgi_req->socket->proto_accept(wsgi_req, uwsgi.zmq_socket->fd); } } else { wsgi_req->poll.fd = wsgi_req->socket->proto_accept(wsgi_req, uwsgi.zmq_socket->fd); } if (wsgi_req->poll.fd >= 0) { wsgi_req_recv(wsgi_req); } uwsgi_close_request(wsgi_req); } // end of the loop return NULL; }