manoj       99/04/19 18:31:04

  Modified:    pthreads/src/main http_main.c
  Log:
  Bug fix for scoreboard handling. Before, if only a single child thread
  was dead, we assumed that the whole child was dead and reused its slot,
  even if there are other threads still running in that process slot.
  
  Now, we actually check two conditions: any_dying_threads and
  all_dead_threads. If any_dying_threads, we make sure not to count this
  as a non-dead process that can be told to die. If all_dead_threads, we
  can reuse the process slot.
  
  Revision  Changes    Path
  1.75      +38 -29    apache-apr/pthreads/src/main/http_main.c
  
  Index: http_main.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/pthreads/src/main/http_main.c,v
  retrieving revision 1.74
  retrieving revision 1.75
  diff -u -u -r1.74 -r1.75
  --- http_main.c       1999/04/17 05:10:18     1.74
  +++ http_main.c       1999/04/20 01:31:03     1.75
  @@ -1934,6 +1934,7 @@
       sigset_t sig_mask;
       int signal_received;
       pthread_t thread;
  +    int j;
   
       my_pid = getpid();
   
  @@ -1982,6 +1983,13 @@
       switch (signal_received) {
           case SIGWINCH:
                    graceful_sig_handler(SIGWINCH);
  +         for (j = 0; j < ap_threads_per_child + ap_acceptors_per_child; 
  +              j++) { 
  +                /* Useful for debugging */
  +                if (ap_scoreboard_image->servers[child_num_arg][j].status != 
SERVER_DEAD) {
  +                    ap_scoreboard_image->servers[child_num_arg][j].status = 
SERVER_GRACEFUL;
  +                }
  +         } 
               graceful_killer();
               clean_child_exit(0);
            break;
  @@ -2121,47 +2129,48 @@
        /* Initialization to satisfy the compiler. It doesn't know
         * that ap_threads_per_child is always > 0 */
        int status = SERVER_DEAD;
  -     idle_thread_count = 0;
  +     int any_dying_threads = 0;
  +     int all_dead_threads = 1;
   
  +     idle_thread_count = 0;
        if (i >= max_daemons_limit && free_length == idle_spawn_rate)
            break;
        for (j = 0; j < ap_threads_per_child; j++) {
               ss = &ap_scoreboard_image->servers[i][j];
            status = ss->status;
  -         if (status == SERVER_DEAD) {
  -             /* try to keep children numbers as low as possible */
  -             if (free_length < idle_spawn_rate) {
  -                 free_slots[free_length] = i;
  -                 ++free_length;
  -                 /* We are killing this process, let's leave the loop */
  -                 break;
  -             }
  -         }
  -         else {
  -             /* We consider a starting server as idle because we started it
  -              * at least a cycle ago, and if it still hasn't finished 
starting
  -              * then we're just going to swamp things worse by forking more.
  -              * So we hopefully won't need to fork more if we count it.
  -              * This depends on the ordering of SERVER_READY and 
SERVER_STARTING.
  +
  +         any_dying_threads = any_dying_threads || (status == SERVER_DEAD)
  +                                    || (status == SERVER_GRACEFUL);
  +         all_dead_threads = all_dead_threads && (status == SERVER_DEAD);
  +
  +         /* We consider a starting server as idle because we started it
  +          * at least a cycle ago, and if it still hasn't finished starting
  +          * then we're just going to swamp things worse by forking more.
  +          * So we hopefully won't need to fork more if we count it.
  +          * This depends on the ordering of SERVER_READY and SERVER_STARTING.
  +          */
  +         if (status <= SERVER_READY) {
  +             ++ idle_thread_count;
  +             /* always kill the highest numbered child if we have to...
  +              * no really well thought out reason ... other than observing
  +              * the server behaviour under linux where lower numbered 
children
  +              * tend to service more hits (and hence are more likely to have
  +              * their data in cpu caches).
                 */
  -             if (status <= SERVER_READY) {
  -                 ++ idle_thread_count;
  -                 /* always kill the highest numbered child if we have to...
  -                  * no really well thought out reason ... other than 
observing
  -                  * the server behaviour under linux where lower numbered 
children
  -                  * tend to service more hits (and hence are more likely to 
have
  -                  * their data in cpu caches).
  -                  */
  -             }
            }
        }
  -     if (idle_thread_count > ap_idle_thread_threshold) {
  -         idle_count++;
  -         to_kill = i;
  +     if (all_dead_threads && free_length < idle_spawn_rate) {
  +         free_slots[free_length] = i;
  +         ++free_length;
        }
  -        if (status != SERVER_DEAD) {
  +        if (!any_dying_threads) {
               ++total_non_dead;
               last_non_dead = i;
  +    
  +            if (idle_thread_count > ap_idle_thread_threshold) {
  +                idle_count++;
  +                to_kill = i;
  +            }
           }
       }
       max_daemons_limit = last_non_dead + 1;
  
  
  

Reply via email to