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) {