#include "uwsgi.h" extern struct uwsgi_server uwsgi; int uwsgi_master_manage_events(int interesting_fd) { // is a logline ? if (uwsgi.log_master && !uwsgi.threaded_logger) { // stderr log ? if (interesting_fd == uwsgi.shared->worker_log_pipe[0]) { uwsgi_master_log(); return 0; } // req log ? if (uwsgi.req_log_master && interesting_fd == uwsgi.shared->worker_req_log_pipe[0]) { uwsgi_master_req_log(); return 0; } } if (uwsgi.master_fifo_fd > -1 && interesting_fd == uwsgi.master_fifo_fd) { return uwsgi_master_fifo_manage(uwsgi.master_fifo_fd); } if (uwsgi.notify_socket_fd > -1 && interesting_fd == uwsgi.notify_socket_fd) { return uwsgi_notify_socket_manage(interesting_fd); } // stats server ? if (uwsgi.stats && uwsgi.stats_fd > -1) { if (interesting_fd == uwsgi.stats_fd) { uwsgi_send_stats(uwsgi.stats_fd, uwsgi_master_generate_stats); return 0; } } // a zerg connection ? if (uwsgi.zerg_server) { if (interesting_fd == uwsgi.zerg_server_fd) { uwsgi_manage_zerg(uwsgi.zerg_server_fd, 0, NULL); return 0; } } // emperor event ? if (uwsgi.has_emperor) { if (uwsgi.emperor_fd_proxy > -1 && interesting_fd == uwsgi.emperor_fd_proxy) { uwsgi_master_manage_emperor_proxy(uwsgi.emperor_fd_proxy, uwsgi.emperor_fd, uwsgi.emperor_fd_config, -1); return 0; } if (interesting_fd == uwsgi.emperor_fd) { uwsgi_master_manage_emperor(); return 0; } } #ifdef __linux__ if (uwsgi.setns_socket && uwsgi.setns_socket_fd > -1 && interesting_fd == uwsgi.setns_socket_fd) { uwsgi_master_manage_setns(uwsgi.setns_socket_fd); } #endif if (uwsgi_fsmon_event(interesting_fd)) { return 0; } // reload on fd if (uwsgi.reload_on_fd) { // custom -> fd // custom2 -> len (optional, default 1) // custom_ptr -> log message (optional) struct uwsgi_string_list *usl = uwsgi.reload_on_fd; while(usl) { if (interesting_fd == (int) usl->custom) { char stack_tmp[8]; char *tmp = stack_tmp; if (usl->custom2 > 8) { tmp = uwsgi_malloc(usl->custom2); } if (read(interesting_fd, tmp, usl->custom2) <= 0) { uwsgi_error("[reload-on-fd] read()"); } if (usl->custom_ptr) { uwsgi_log_verbose("*** fd %d ready: %s ***\n", interesting_fd, usl->custom_ptr); } else { uwsgi_log_verbose("*** fd %d ready !!! ***\n", interesting_fd); } uwsgi_block_signal(SIGHUP); grace_them_all(0); uwsgi_unblock_signal(SIGHUP); return 0; } usl = usl->next; } } // brutal reload on fd if (uwsgi.brutal_reload_on_fd) { // custom -> fd // custom2 -> len (optional, default 1) // custom_ptr -> log message (optional) struct uwsgi_string_list *usl = uwsgi.brutal_reload_on_fd; while(usl) { if (interesting_fd == (int) usl->custom) { char stack_tmp[8]; char *tmp = stack_tmp; if (usl->custom2 > 8) { tmp = uwsgi_malloc(usl->custom2); } if (read(interesting_fd, tmp, usl->custom2) <= 0) { uwsgi_error("[brutal-reload-on-fd] read()"); } if (usl->custom_ptr) { uwsgi_log_verbose("*** fd %d ready: %s ***\n", interesting_fd, usl->custom_ptr); } else { uwsgi_log_verbose("*** fd %d ready !!! ***\n", interesting_fd); } uwsgi_block_signal(SIGQUIT); reap_them_all(0); uwsgi_unblock_signal(SIGQUIT); if (usl->custom2 > 8) free(tmp); return 0; } usl = usl->next; } } // wakeup from cheap mode ? if (uwsgi.status.is_cheap) { struct uwsgi_socket *uwsgi_sock = uwsgi.sockets; while (uwsgi_sock) { if (interesting_fd == uwsgi_sock->fd) { uwsgi.status.is_cheap = 0; uwsgi_del_sockets_from_queue(uwsgi.master_queue); // how many worker we need to respawn ? int needed = uwsgi.numproc; // if in cheaper mode, just respawn the minimal amount if (uwsgi.cheaper) { needed = uwsgi.cheaper_count; } int i; for (i = 1; i <= needed; i++) { if (uwsgi_respawn_worker(i)) return -1; } // here we continue instead of returning break; } uwsgi_sock = uwsgi_sock->next; } } // an SNMP request ? if (uwsgi.snmp_addr && interesting_fd == uwsgi.snmp_fd) { uwsgi_master_manage_snmp(uwsgi.snmp_fd); return 0; } // a UDP request ? if (uwsgi.udp_socket && interesting_fd == uwsgi.udp_fd) { uwsgi_master_manage_udp(uwsgi.udp_fd); return 0; } // check if some file monitor is ready // no need to lock as we are only getting registered items (and only the master can register them) int i; for (i = 0; i < ushared->files_monitored_cnt; i++) { if (ushared->files_monitored[i].registered) { if (interesting_fd == ushared->files_monitored[i].fd) { struct uwsgi_fmon *uf = event_queue_ack_file_monitor(uwsgi.master_queue, interesting_fd); // now call the file_monitor handler if (uf) uwsgi_route_signal(uf->sig); return 0; } } } // check if some timer elapsed // no need to lock again for (i = 0; i < ushared->timers_cnt; i++) { if (ushared->timers[i].registered) { if (interesting_fd == ushared->timers[i].fd) { struct uwsgi_timer *ut = event_queue_ack_timer(interesting_fd); // now call the timer handler if (ut) uwsgi_route_signal(ut->sig); return 0; } } } uint8_t uwsgi_signal; // check for worker signal if (interesting_fd == uwsgi.shared->worker_signal_pipe[0]) { ssize_t rlen = read(interesting_fd, &uwsgi_signal, 1); if (rlen < 0) { uwsgi_error("uwsgi_master_manage_events()/read()"); } else if (rlen > 0) { uwsgi_route_signal(uwsgi_signal); } else { // TODO restart workers here uwsgi_log_verbose("lost connection with workers !!!\n"); close(interesting_fd); } return 0; } // check for spooler signal if (uwsgi.spoolers) { if (interesting_fd == uwsgi.shared->spooler_signal_pipe[0]) { ssize_t rlen = read(interesting_fd, &uwsgi_signal, 1); if (rlen < 0) { uwsgi_error("uwsgi_master_manage_events()/read()"); } else if (rlen > 0) { uwsgi_route_signal(uwsgi_signal); } else { // TODO restart spoolers here uwsgi_log_verbose("lost connection with spoolers\n"); close(interesting_fd); } return 0; } } // check for mules signal if (uwsgi.mules_cnt > 0) { if (interesting_fd == uwsgi.shared->mule_signal_pipe[0]) { ssize_t rlen = read(interesting_fd, &uwsgi_signal, 1); if (rlen < 0) { uwsgi_error("uwsgi_master_manage_events()/read()"); } else if (rlen > 0) { uwsgi_route_signal(uwsgi_signal); } else { // TODO respawn mules here uwsgi_log_verbose("lost connection with mules\n"); close(interesting_fd); } // return 0; } } return 0; }