Index: server/mpm/event/event.c =================================================================== --- server/mpm/event/event.c (revision 1820131) +++ server/mpm/event/event.c (working copy) @@ -470,6 +470,8 @@ static pid_t ap_my_pid; /* Linux getpid() static pid_t parent_pid; static apr_os_thread_t *listener_os_thread; +static int ap_child_slot; /* Current child process slot in scoreboard */ + /* The LISTENER_SIGNAL signal will be sent from the main thread to the * listener thread to wake it up for graceful termination (what a child * process from an old generation does when the admin does "apachectl @@ -483,20 +485,25 @@ static apr_os_thread_t *listener_os_thread; */ static apr_socket_t **worker_sockets; -static void disable_listensocks(int process_slot) +static void disable_listensocks(void) { int i; + if (listeners_disabled) { + return; + } listeners_disabled = 1; - for (i = 0; i < num_listensocks; i++) { - apr_pollset_remove(event_pollset, &listener_pollfd[i]); + if (event_pollset) { + for (i = 0; i < num_listensocks; i++) { + apr_pollset_remove(event_pollset, &listener_pollfd[i]); + } } - ap_scoreboard_image->parent[process_slot].not_accepting = 1; + ap_scoreboard_image->parent[ap_child_slot].not_accepting = 1; } -static void enable_listensocks(int process_slot) +static void enable_listensocks(void) { int i; - if (listener_may_exit) { + if (!listeners_disabled || listener_may_exit) { return; } listeners_disabled = 0; @@ -515,7 +522,7 @@ static apr_socket_t **worker_sockets; * XXX: This is not yet optimal. If many workers suddenly become available, * XXX: the parent may kill some processes off too soon. */ - ap_scoreboard_image->parent[process_slot].not_accepting = 0; + ap_scoreboard_image->parent[ap_child_slot].not_accepting = 0; } static APR_INLINE int connections_above_limit(void) @@ -590,6 +597,7 @@ static void close_worker_sockets(void) static void wakeup_listener(void) { listener_may_exit = 1; + disable_listensocks(); /* Unblock the listener if it's poll()ing */ if (event_pollset && listener_is_wakeable) { @@ -1270,17 +1278,16 @@ static void check_infinite_requests(void) } } -static void close_listeners(int process_slot, int *closed) +static void close_listeners(int *closed) { if (!*closed) { int i; - disable_listensocks(process_slot); ap_close_listeners_ex(my_bucket->listeners); *closed = 1; dying = 1; - ap_scoreboard_image->parent[process_slot].quiescing = 1; + ap_scoreboard_image->parent[ap_child_slot].quiescing = 1; for (i = 0; i < threads_per_child; ++i) { - ap_update_child_status_from_indexes(process_slot, i, + ap_update_child_status_from_indexes(ap_child_slot, i, SERVER_GRACEFUL, NULL); } /* wake up the main thread */ @@ -1794,8 +1801,9 @@ static void * APR_THREAD_FUNC listener_thread(apr_ ap_log_error(APLOG_MARK, APLOG_ERR, rc, ap_server_conf, APLOGNO(03266) "failed to initialize pollset, " - "attempting to shutdown process gracefully"); - signal_threads(ST_GRACEFUL); + "shutdown process now"); + resource_shortage = 1; + signal_threads(ST_UNGRACEFUL); return NULL; } @@ -1817,7 +1825,7 @@ static void * APR_THREAD_FUNC listener_thread(apr_ check_infinite_requests(); if (listener_may_exit) { - close_listeners(process_slot, &closed); + close_listeners(&closed); if (terminate_mode == ST_UNGRACEFUL || apr_atomic_read32(&connection_count) == 0) break; @@ -1942,13 +1950,13 @@ static void * APR_THREAD_FUNC listener_thread(apr_ } if (listener_may_exit) { - close_listeners(process_slot, &closed); + close_listeners(&closed); if (terminate_mode == ST_UNGRACEFUL || apr_atomic_read32(&connection_count) == 0) break; } - while (num) { + for (; num; --num, ++out_pfd) { listener_poll_type *pt = (listener_poll_type *) out_pfd->client_data; if (pt->type == PT_CSD) { /* one of the sockets is readable */ @@ -2012,7 +2020,7 @@ static void * APR_THREAD_FUNC listener_thread(apr_ else if (pt->type == PT_ACCEPT && !listeners_disabled) { /* A Listener Socket is ready for an accept() */ if (workers_were_busy) { - disable_listensocks(process_slot); + disable_listensocks(); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03268) "All workers busy, not accepting new conns " @@ -2019,7 +2027,7 @@ static void * APR_THREAD_FUNC listener_thread(apr_ "in this process"); } else if (connections_above_limit()) { - disable_listensocks(process_slot); + disable_listensocks(); ap_log_error(APLOG_MARK, APLOG_DEBUG, 0, ap_server_conf, APLOGNO(03269) "Too many open connections (%u), " @@ -2048,8 +2056,9 @@ static void * APR_THREAD_FUNC listener_thread(apr_ ap_server_conf, APLOGNO(03097) "Failed to create transaction pool"); apr_allocator_destroy(allocator); + resource_shortage = 1; signal_threads(ST_GRACEFUL); - return NULL; + continue; } apr_allocator_owner_set(allocator, ptrans); } @@ -2118,9 +2127,7 @@ static void * APR_THREAD_FUNC listener_thread(apr_ push_timer2worker(te); } } - out_pfd++; - num--; - } /* while for processing poll */ + } /* for processing poll */ /* XXX possible optimization: stash the current time for use as * r->request_time for new requests @@ -2195,11 +2202,11 @@ static void * APR_THREAD_FUNC listener_thread(apr_ if (listeners_disabled && !workers_were_busy && !connections_above_limit()) { - enable_listensocks(process_slot); + enable_listensocks(); } } /* listener main loop */ - close_listeners(process_slot, &closed); + close_listeners(&closed); ap_queue_term(worker_queue); apr_thread_exit(thd, APR_SUCCESS); @@ -2649,6 +2656,7 @@ static void child_main(int child_num_arg, int chil retained->mpm->mpm_state = AP_MPMQ_STARTING; ap_my_pid = getpid(); + ap_child_slot = child_num_arg; ap_fatal_signal_child_setup(ap_server_conf); apr_pool_create(&pchild, pconf);