]> git.ipfire.org Git - thirdparty/apache/httpd.git/commitdiff
Win32: The Apache Win32 developers generally recommend that
authorBill Stoddard <stoddard@apache.org>
Wed, 17 Oct 2001 14:45:29 +0000 (14:45 +0000)
committerBill Stoddard <stoddard@apache.org>
Wed, 17 Oct 2001 14:45:29 +0000 (14:45 +0000)
MaxRequestsPerChild be set to 0 to prevent the child process
from ever recycling. However, for those that do require a
non-zero setting, this patch fixes a serious bug that can cause
an apparent 'server-hang' condition where the server stops
responding to requests for a period of time. Prior to this
fix, when the child process handled MaxRequestsPerChild
connnections, the child process would stop accepting new
connections and begin allowing inactive threads to exit. The
problem was that a new process would not be created to begin
handling requests until the old process fully exited. The old
process can take an indeterminate amount of time to exit because
it may be sending large responses to clients connected over slow
links, or it may have threads blocked in read awaiting requests
(eg, one attack mode of the Nimda worm is to establish a
connection to the server but not send an HTTP request. This
connection will be timed out according to the setting of the
Timeout directive, 300 seconds). This fix allows the new process
to be immediately started and begin accepting requests when the
old child process reaches MaxRequestsPerChild.

git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/branches/1.3.x@91523 13f79535-47bb-0310-9956-ffa450edef68

src/CHANGES
src/main/http_main.c

index 2ec5c567995e2d52e68c15dccfaa9357a377e578..0937e2e5e797473d182a6a5aa8b256155560bd48 100644 (file)
@@ -1,4 +1,26 @@
 Changes with Apache 1.3.23
+  *) Win32: The Apache Win32 developers generally recommend that
+     MaxRequestsPerChild be set to 0 to prevent the child process
+     from ever recycling. However, for those that do require a 
+     non-zero setting, this patch fixes a serious bug that can cause 
+     an apparent 'server-hang' condition where the server stops
+     responding to requests for a period of time. Prior to this
+     fix, when the child process handled MaxRequestsPerChild
+     connnections, the child process would stop accepting new 
+     connections and begin allowing inactive threads to exit. The
+     problem was that a new process would not be created to begin
+     handling requests until the old process fully exited. The old 
+     process can take an indeterminate amount of time to exit because
+     it may be sending large responses to clients connected over slow
+     links, or it may have threads blocked in read awaiting requests
+     (eg, one attack mode of the Nimda worm is to establish a 
+     connection to the server but not send an HTTP request. This 
+     connection will be timed out according to the setting of the
+     Timeout directive, 300 seconds). This fix allows the new process
+     to be immediately started and begin accepting requests when the 
+     old child process reaches MaxRequestsPerChild. 
+     [Bill Stoddard]
+     
   *) Win32: Emit error message when the server bumps up against the
      ThreadsPerChild configuration limit. This will be useful for 
      admins to detect when their server is running out of threads
index a58bd684950b0c7d0fb96767f08510cc3c326c79..425e2d88d2969fc8f4a13818f049db0d5b383504 100644 (file)
@@ -5616,8 +5616,8 @@ int remove_job(int csd)
     if (!reported && (active_threads == ap_threads_per_child)) {
         reported = 1;
         ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_ERR, server_conf,
-                     "server reached ThreadsPerChild setting, consider"
-                     " raising the ThreadsPerChild setting");
+                     "Server ran out of threads to serve requests. Consider "
+                     "raising the ThreadsPerChild setting");
     }
     return (sock);
 }
@@ -6279,8 +6279,10 @@ void worker_main(void)
 
     while (1) {
         if (max_jobs_per_exe && (total_jobs > max_jobs_per_exe)) {
-            /* MaxRequestsPerChild hit...
+            /* Reached MaxRequestsPerChild. Stop accepting new connections
+             * and signal the parent to start a new child process.
              */
+            ap_start_restart(1);
             break;
        }
         /* Always check for the exit event being signaled.
@@ -6796,7 +6798,11 @@ int master_main(int argc, char **argv)
            }
             break;
         } else if (cld == current_live_processes+1) {
-            /* apPID_restart event signalled, restart the child process */
+            /* apPID_restart event signalled. 
+             * Signal the child to shutdown and start a new child process.
+             * The restart event can be signaled by a command line restart or
+             * by the child process when it handles MaxRequestPerChild connections.
+             */
             int children_to_kill = current_live_processes;
             restart_pending = 1;
             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf, 
@@ -6814,17 +6820,15 @@ int master_main(int argc, char **argv)
                 /* Remove the process (and event) from the process table */
                 cleanup_process(process_handles, process_kill_events, i, &current_live_processes);
            }
-           processes_to_create = nchild;
+           processes_to_create = 1;
             ++ap_my_generation;
             continue;
         } else {
-            /* A child process must have exited because of MaxRequestPerChild being hit
-             * or a fatal error condition (seg fault, etc.). Remove the dead process 
-             * from the process_handles and process_kill_events table and create a new
-             * child process.
+            /* The child process exited premeturely because of a fatal error condition
+             * (eg, seg fault). Cleanup and restart the child process.
              */
             ap_log_error(APLOG_MARK, APLOG_NOERRNO|APLOG_INFO, server_conf, 
-                         "master_main: Child processed exited (due to MaxRequestsPerChild?). Restarting the child process.");
+                         "master_main: Child processed exited prematurely. Restarting the child process.");
            ap_assert(cld < current_live_processes);
            cleanup_process(process_handles, process_kill_events, cld, &current_live_processes);
            APD2("main_process: child in slot %d died", rv);