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

Reply via email to