httpd-cvs mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From grega...@apache.org
Subject cvs commit: httpd-2.0/server/mpm/threaded threaded.c
Date Mon, 23 Apr 2001 02:13:17 GMT
gregames    01/04/22 19:13:17

  Modified:    .        CHANGES
               include  scoreboard.h
               server/mpm/threaded threaded.c
  Log:
  Limit the threaded mpm to quiescing one process at a time.
  
  This is to fix a problem where the scoreboard is filled with
  quiescing processes and no working processes can start, triggered by
  MaxRequestsPerChild.  perform_idle_server_maintenance could theoretically
  cause it as well.
  
  Revision  Changes    Path
  1.182     +6 -1      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.181
  retrieving revision 1.182
  diff -u -d -b -u -r1.181 -r1.182
  --- CHANGES	2001/04/22 22:19:26	1.181
  +++ CHANGES	2001/04/23 02:13:16	1.182
  @@ -1,5 +1,10 @@
   Changes with Apache 2.0.18-dev
   
  +  *) Limit the threaded mpm to quiescing one process at a time.
  +     This is to fix a problem where the scoreboard is filled with
  +     quiescing processes and no working processes can start.
  +     [Greg Ames]
  +     
     *) Change how input filters decide how much data is returned to the
        higher filter.  We used to use a field in the conn_rec, with this
        change, we use an argument to ap_get_brigade to determine how much
  
  
  
  1.16      +5 -0      httpd-2.0/include/scoreboard.h
  
  Index: scoreboard.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/include/scoreboard.h,v
  retrieving revision 1.15
  retrieving revision 1.16
  diff -u -d -b -u -r1.15 -r1.16
  --- scoreboard.h	2001/04/06 20:11:59	1.15
  +++ scoreboard.h	2001/04/23 02:13:16	1.16
  @@ -189,6 +189,11 @@
       ap_scoreboard_e sb_type;
       ap_generation_t running_generation;	/* the generation of children which
                                            * should still be serving requests. */
  +#if APR_HAS_THREADS
  +    pid_t quiescing_pid;                /* pid of process which is going down
  +                                         * due to MaxRequestsPerChild or
  +                                         * perform_idle_server_maintanence   */
  +#endif 
   } global_score;
   
   /* stuff which the parent generally writes and the children rarely read */
  
  
  
  1.24      +36 -8     httpd-2.0/server/mpm/threaded/threaded.c
  
  Index: threaded.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/mpm/threaded/threaded.c,v
  retrieving revision 1.23
  retrieving revision 1.24
  diff -u -d -b -u -r1.23 -r1.24
  --- threaded.c	2001/04/14 21:06:48	1.23
  +++ threaded.c	2001/04/23 02:13:17	1.24
  @@ -200,6 +200,9 @@
   static void clean_child_exit(int code) __attribute__ ((noreturn));
   static void clean_child_exit(int code)
   {
  +    if (ap_scoreboard_image->global.quiescing_pid == ap_my_pid) {
  +        ap_scoreboard_image->global.quiescing_pid = 0;
  +    }
       if (pchild) {
   	apr_pool_destroy(pchild);
       }
  @@ -211,6 +214,12 @@
   {
       chdir(ap_coredump_dir);
       apr_signal(sig, SIG_DFL);
  +    
  +    /* clean up so that other processes can quiesce */
  +    if (ap_scoreboard_image->global.quiescing_pid == ap_my_pid) {
  +        ap_scoreboard_image->global.quiescing_pid = 0;
  +    }
  +    
       kill(ap_my_pid, sig);
       /* At this point we've got sig blocked, because we're still inside
        * the signal handler.  When we leave the signal handler it will
  @@ -487,7 +496,9 @@
       /* TODO: Switch to a system where threads reuse the results from earlier
          poll calls - manoj */
       while (1) {
  -        workers_may_exit |= (ap_max_requests_per_child != 0) && (requests_this_child
<= 0);
  +        workers_may_exit |= (ap_max_requests_per_child != 0) 
  +                             && (requests_this_child <= 0)
  +                             && (ap_scoreboard_image->global.quiescing_pid ==
0);
           if (workers_may_exit) break;
   
           (void) ap_update_child_status(process_slot, thread_slot, SERVER_READY, 
  @@ -581,14 +592,22 @@
           apr_pool_clear(ptrans);
       }
   
  +    if (ap_scoreboard_image->global.quiescing_pid == 0) {
  +        /* yeah, I realize there's a race condition here, but it works 
  +         * out OK without serialization                               */ 
  +        ap_scoreboard_image->global.quiescing_pid = ap_my_pid;   
  +    }
       apr_pool_destroy(tpool);
       ap_update_child_status(process_slot, thread_slot, SERVER_DEAD,
           (request_rec *) NULL);
       apr_lock_acquire(worker_thread_count_mutex);
       worker_thread_count--;
       if (worker_thread_count == 0) {
  -        /* All the threads have exited, now finish the shutdown process
  -         * by signalling the sigwait thread */
  +        /* All the threads have exited, now finish the shutdown process */
  +        if (ap_scoreboard_image->global.quiescing_pid == ap_my_pid) {
  +            ap_scoreboard_image->global.quiescing_pid = 0;
  +        }
  +        /* signal the sigwait thread */
           kill(ap_my_pid, SIGTERM);
       }
       apr_lock_release(worker_thread_count_mutex);
  @@ -858,11 +877,18 @@
   	        ++idle_thread_addition;
   	    }
   	}
  -	if (all_dead_threads && free_length < idle_spawn_rate) {
  +	if (all_dead_threads) {
  +            pid_t dead_pid = ap_scoreboard_image->parent[i].pid; 
  +            if (ap_scoreboard_image->global.quiescing_pid == dead_pid) {
  +                /* shouldn't happen, but just in case... */
  +                ap_scoreboard_image->global.quiescing_pid = 0;
  +            }
  +            if (free_length < idle_spawn_rate) {
   	    free_slots[free_length] = i;
   	    ++free_length;
   	}
  -	if (!all_dead_threads) {
  +	}
  +	else {                       /* ! all_dead_threads */
               last_non_dead = i;
   	}
           if (!any_dying_threads) {
  @@ -872,7 +898,8 @@
       }
       ap_max_daemons_limit = last_non_dead + 1;
   
  -    if (idle_thread_count > max_spare_threads) {
  +    if (idle_thread_count > max_spare_threads 
  +        &&  ap_scoreboard_image->global.quiescing_pid == 0) {
           /* Kill off one child */
           char char_of_death = '!';
           if ((rv = apr_file_write(pipe_of_death_out, &char_of_death, &one)) != APR_SUCCESS)
{
  @@ -1114,6 +1141,7 @@
        */
       ++ap_my_generation;
       ap_scoreboard_image->global.running_generation = ap_my_generation;
  +    ap_scoreboard_image->global.quiescing_pid = 0;
       update_scoreboard_global();
   
       if (is_graceful) {
  
  
  

Mime
View raw message