You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by tr...@apache.org on 2002/03/18 19:24:55 UTC

cvs commit: httpd-2.0/server/mpm/prefork prefork.c

trawick     02/03/18 10:24:55

  Modified:    .        CHANGES
               server   mpm_common.c
               server/mpm/prefork prefork.c
  Log:
  Fix a hang condition with graceful restart and prefork MPM
  in the situation where MaxClients is very high but
  much fewer servers are actually started at the time of the
  restart.
  
  The way we notify an entire generation to die at once is
  changed so that we don't have to use the pod (and deal with
  the ease of filling the kernel pipe buffer).
  
  Revision  Changes    Path
  1.640     +5 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.639
  retrieving revision 1.640
  diff -u -r1.639 -r1.640
  --- CHANGES	17 Mar 2002 17:47:24 -0000	1.639
  +++ CHANGES	18 Mar 2002 18:24:55 -0000	1.640
  @@ -1,5 +1,10 @@
   Changes with Apache 2.0.34-dev
   
  +  *) Fix a hang condition with graceful restart and prefork MPM
  +     in the situation where MaxClients is very high but
  +     much fewer servers are actually started at the time of the
  +     restart.  [Jeff Trawick]
  +
     *) Small performance fixes for mod_include [Brian Pane]
   
     *) Performance improvement for the error logger [Brian Pane]
  
  
  
  1.88      +14 -7     httpd-2.0/server/mpm_common.c
  
  Index: mpm_common.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/mpm_common.c,v
  retrieving revision 1.87
  retrieving revision 1.88
  diff -u -r1.87 -r1.88
  --- mpm_common.c	18 Mar 2002 16:39:56 -0000	1.87
  +++ mpm_common.c	18 Mar 2002 18:24:55 -0000	1.88
  @@ -540,14 +540,21 @@
       int i;
       apr_status_t rv = APR_SUCCESS;
   
  +    /* we don't write anything to the pod here...  we assume
  +     * that the would-be reader of the pod has another way to
  +     * see that it is time to die once we wake it up
  +     *
  +     * writing lots of things to the pod at once is very
  +     * problematic... we can fill the kernel pipe buffer and
  +     * be blocked until somebody consumes some bytes or
  +     * we hit a timeout...  if we hit a timeout we can't just
  +     * keep trying because maybe we'll never successfully
  +     * write again...  but then maybe we'll leave would-be
  +     * readers stranded (a number of them could be tied up for
  +     * a while serving time-consuming requests)
  +     */
       for (i = 0; i < num && rv == APR_SUCCESS; i++) {
  -        rv = pod_signal_internal(pod);
  -    }
  -
  -    if (rv == APR_SUCCESS) {
  -        for (i = 0; i < num && rv == APR_SUCCESS; i++) {
  -             rv = dummy_connection(pod);
  -        }
  +        rv = dummy_connection(pod);
       }
   }
   #endif /* #ifdef AP_MPM_USES_POD */
  
  
  
  1.251     +12 -7     httpd-2.0/server/mpm/prefork/prefork.c
  
  Index: prefork.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/mpm/prefork/prefork.c,v
  retrieving revision 1.250
  retrieving revision 1.251
  diff -u -r1.250 -r1.251
  --- prefork.c	18 Mar 2002 18:12:43 -0000	1.250
  +++ prefork.c	18 Mar 2002 18:24:55 -0000	1.251
  @@ -675,14 +675,19 @@
               ap_lingering_close(current_conn);
           }
           
  -        /* Check the pod after processing a connection so that we'll go away
  -         * if a graceful restart occurred while we were processing the 
  -         * connection.  Otherwise, we won't wake up until a real connection 
  -         * comes in and we'll use the wrong config to process it and we may
  -         * block in the wrong syscall (because the new generation is using a
  -         * different accept mutex) and in general it is goofy.
  +        /* Check the pod and the generation number after processing a
  +         * connection so that we'll go away if a graceful restart occurred
  +         * while we were processing the connection or we are the lucky
  +         * idle server process that gets to die.
            */
  -        if (!ap_mpm_pod_check(pod)) {
  +        if (ap_mpm_pod_check(pod) == APR_SUCCESS) { /* selected as idle? */
  +            die_now = 1;
  +        }
  +        else if (ap_my_generation !=
  +                 ap_scoreboard_image->global->running_generation) { /* restart? */
  +            /* yeah, this could be non-graceful restart, in which case the
  +             * parent will kill us soon enough, but why bother checking?
  +             */
               die_now = 1;
           }
           ap_sync_scoreboard_image();