This ugly thing kills off threads that are running long-lived requests when we want to do a graceless shutdown of the server. I tested it by running ab with concurrency of 100 against a 10MB file and running "bin/apachectl stop ; ps -ef | grep httpd". I get a bunch of [info] errors in the error log of this form:
[Sun Apr 28 17:04:26 2002] [info] (9)Bad file number: core_output_filter: writing data to the network But hey, when you're killing off your server gracelessly what do you expect? We might want to add an error message before all those core_output_filters that is something like "We're going to prematurely kill off all the current connections now..." -aaron Index: server/mpm/worker/worker.c =================================================================== RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v retrieving revision 1.120 diff -u -r1.120 worker.c --- server/mpm/worker/worker.c 28 Apr 2002 22:13:32 -0000 1.120 +++ server/mpm/worker/worker.c 29 Apr 2002 00:05:04 -0000 @@ -252,6 +252,21 @@ */ #define LISTENER_SIGNAL SIGHUP +/* An array of socket descriptors in use by each thread used to + * perform a non-graceful (forced) shutdown of the server. */ +static apr_socket_t **worker_sockets; + +static void close_worker_sockets(void) +{ + int i; + for (i = 0; i < ap_threads_per_child; i++) { + if (worker_sockets[i]) { + apr_socket_close(worker_sockets[i]); + worker_sockets[i] = NULL; + } + } +} + static void wakeup_listener(void) { listener_may_exit = 1; @@ -301,6 +316,7 @@ workers_may_exit = 1; ap_queue_interrupt_all(worker_queue); ap_queue_info_term(worker_queue_info); + close_worker_sockets(); /* forcefully kill all current connections */ } } @@ -912,7 +928,9 @@ } continue; } + worker_sockets[thread_slot] = csd; process_socket(ptrans, csd, process_slot, thread_slot, bucket_alloc); + worker_sockets[thread_slot] = NULL; requests_this_child--; /* FIXME: should be synchronized - aaron */ apr_pool_clear(ptrans); last_ptrans = ptrans; @@ -1001,6 +1019,10 @@ "ap_queue_info_create() failed"); clean_child_exit(APEXIT_CHILDFATAL); } + + worker_sockets = apr_palloc(pchild, ap_threads_per_child + * sizeof(apr_socket_t *)); + memset(worker_sockets, 0, ap_threads_per_child * sizeof(apr_socket_t *)); loops = prev_threads_created = 0; while (1) {