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/21 20:12:54 UTC

cvs commit: httpd-2.0/server/mpm/worker fdqueue.c fdqueue.h worker.c

trawick     02/03/21 11:12:54

  Modified:    .        CHANGES
               server/mpm/worker fdqueue.c fdqueue.h worker.c
  Log:
  Don't drop connections during graceful restart.  Previously, worker
  threads could exit even though there were connections waiting in the
  queue.
  
  Now, for a graceful restart the worker threads won't exit until they
  are told that the queue has been drained and no more connections will
  ever be added.
  
  Revision  Changes    Path
  1.651     +3 -0      httpd-2.0/CHANGES
  
  Index: CHANGES
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/CHANGES,v
  retrieving revision 1.650
  retrieving revision 1.651
  diff -u -r1.650 -r1.651
  --- CHANGES	21 Mar 2002 12:05:45 -0000	1.650
  +++ CHANGES	21 Mar 2002 19:12:54 -0000	1.651
  @@ -1,5 +1,8 @@
   Changes with Apache 2.0.34-dev
   
  +  *) Fix some restart/terminate problems in the worker MPM.  Don't
  +     drop connections during graceful restart.  [Jeff Trawick]
  +
     *) Change the header merging behaviour in proxy, as some headers
        (like Set-Cookie) cannot be unmerged due to stray commas in
        dates. [Graham Leggett]
  
  
  
  1.14      +28 -2     httpd-2.0/server/mpm/worker/fdqueue.c
  
  Index: fdqueue.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/mpm/worker/fdqueue.c,v
  retrieving revision 1.13
  retrieving revision 1.14
  diff -u -r1.13 -r1.14
  --- fdqueue.c	21 Mar 2002 15:27:31 -0000	1.13
  +++ fdqueue.c	21 Mar 2002 19:12:54 -0000	1.14
  @@ -140,6 +140,8 @@
           return rv;
       }
   
  +    AP_DEBUG_ASSERT(!queue->terminated);
  +    
       while (ap_queue_full(queue)) {
           apr_thread_cond_wait(queue->not_full, queue->one_big_mutex);
       }
  @@ -191,13 +193,20 @@
   
       /* Keep waiting until we wake up and find that the queue is not empty. */
       if (ap_queue_empty(queue)) {
  -        apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex);
  +        if (!queue->terminated) {
  +            apr_thread_cond_wait(queue->not_empty, queue->one_big_mutex);
  +        }
           /* If we wake up and it's still empty, then we were interrupted */
           if (ap_queue_empty(queue)) {
               if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) {
                   return rv;
               }
  -            return APR_EINTR;
  +            if (queue->terminated) {
  +                return APR_EOF; /* no more elements ever again */
  +            }
  +            else {
  +                return APR_EINTR;
  +            }
           }
       } 
       
  @@ -236,3 +245,20 @@
       return APR_SUCCESS;
   }
   
  +apr_status_t ap_queue_term(fd_queue_t *queue)
  +{
  +    apr_status_t rv;
  +
  +    if ((rv = apr_thread_mutex_lock(queue->one_big_mutex)) != APR_SUCCESS) {
  +        return rv;
  +    }
  +    /* we must hold one_big_mutex when setting this... otherwise,
  +     * we could end up setting it and waking everybody up just after a 
  +     * would-be popper checks it but right before they block
  +     */
  +    queue->terminated = 1;
  +    if ((rv = apr_thread_mutex_unlock(queue->one_big_mutex)) != APR_SUCCESS) {
  +        return rv;
  +    }
  +    return ap_queue_interrupt_all(queue);
  +}
  
  
  
  1.15      +2 -0      httpd-2.0/server/mpm/worker/fdqueue.h
  
  Index: fdqueue.h
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/mpm/worker/fdqueue.h,v
  retrieving revision 1.14
  retrieving revision 1.15
  diff -u -r1.14 -r1.15
  --- fdqueue.h	21 Mar 2002 15:19:54 -0000	1.14
  +++ fdqueue.h	21 Mar 2002 19:12:54 -0000	1.15
  @@ -86,6 +86,7 @@
       apr_thread_cond_t  *not_full;
       apr_pool_t        **recycled_pools;
       int                 num_recycled;
  +    int                 terminated;
   };
   typedef struct fd_queue_t fd_queue_t;
   
  @@ -95,5 +96,6 @@
   apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p,
                             apr_pool_t *recycled_pool);
   apr_status_t ap_queue_interrupt_all(fd_queue_t *queue);
  +apr_status_t ap_queue_term(fd_queue_t *queue);
   
   #endif /* FDQUEUE_H */
  
  
  
  1.104     +23 -3     httpd-2.0/server/mpm/worker/worker.c
  
  Index: worker.c
  ===================================================================
  RCS file: /home/cvs/httpd-2.0/server/mpm/worker/worker.c,v
  retrieving revision 1.103
  retrieving revision 1.104
  diff -u -r1.103 -r1.104
  --- worker.c	21 Mar 2002 16:31:39 -0000	1.103
  +++ worker.c	21 Mar 2002 19:12:54 -0000	1.104
  @@ -267,17 +267,30 @@
   
   static void signal_threads(int mode)
   {
  +    static int prev_mode = 0;
  +    
  +    if (prev_mode == mode) {
  +        return;
  +    }
  +    prev_mode = mode;
  +
       /* in case we weren't called from the listener thread, wake up the
        * listener thread
        */
       wakeup_listener();
   
  +    /* for ungraceful termination, let the workers exit now;
  +     * for graceful termination, the listener thread will notify the
  +     * workers to exit once it has stopped accepting new connections
  +     */
  +    if (mode == ST_UNGRACEFUL) {
  +        workers_may_exit = 1;
  +        ap_queue_interrupt_all(worker_queue);
  +    }
  +
       /* XXX: This will happen naturally on a graceful, and we don't care 
        * otherwise.
       ap_queue_signal_all_wakeup(worker_queue); */
  -
  -    workers_may_exit = 1;
  -    ap_queue_interrupt_all(worker_queue);
   }
   
   AP_DECLARE(apr_status_t) ap_mpm_query(int query_code, int *result)
  @@ -798,6 +811,7 @@
       ap_update_child_status_from_indexes(process_slot, thread_slot, 
                                           (dying) ? SERVER_DEAD : SERVER_GRACEFUL,
                                           (request_rec *) NULL);
  +    ap_queue_term(worker_queue);
       dying = 1;
       ap_scoreboard_image->parent[process_slot].quiescing = 1;
       kill(ap_my_pid, SIGTERM);
  @@ -832,6 +846,12 @@
           last_ptrans = NULL;
   
           if (rv != APR_SUCCESS) {
  +            /* We get APR_EOF during a graceful shutdown once all the connections
  +             * accepted by this server process have been handled.
  +             */
  +            if (rv == APR_EOF) {
  +                break;
  +            }
               /* We get APR_EINTR whenever ap_queue_pop() has been interrupted
                * from an explicit call to ap_queue_interrupt_all(). This allows
                * us to unblock threads stuck in ap_queue_pop() when a shutdown
  
  
  

Re: cvs commit: httpd-2.0/server/mpm/worker fdqueue.c fdqueue.h worker.c

Posted by Jeff Trawick <tr...@attglobal.net>.
Aaron Bannert <aa...@clove.org> writes:

> Is ap_queue_interrupt_all() used anywhere externally anymore? Let's
> just get rid of it in lieu of ap_queue_term().

That one is still used by worker MPM on the non-graceful shutdown
path.

On my first attempt to get this working I had a parameter to
ap_queue_term() which told it whether or not to nuke the queue before
waking up the threads in ap_queue_pop().  If that were implemented
again then on the non-graceful shutdown path we could call
ap_queue_term(nuke-the-queue) instead of ap_queue_interrupt_all(),
and then we wouldn't need to externalize ap_queue_interrupt_all().

-- 
Jeff Trawick | trawick@attglobal.net
Born in Roswell... married an alien...

Re: cvs commit: httpd-2.0/server/mpm/worker fdqueue.c fdqueue.h worker.c

Posted by Aaron Bannert <aa...@clove.org>.
On Thu, Mar 21, 2002 at 07:12:54PM -0000, trawick@apache.org wrote:
> trawick     02/03/21 11:12:54
> 
>   Modified:    .        CHANGES
>                server/mpm/worker fdqueue.c fdqueue.h worker.c
>   Log:
>   Don't drop connections during graceful restart.  Previously, worker
>   threads could exit even though there were connections waiting in the
>   queue.
>   
>   Now, for a graceful restart the worker threads won't exit until they
>   are told that the queue has been drained and no more connections will
>   ever be added.

Awesome!

Is ap_queue_interrupt_all() used anywhere externally anymore? Let's
just get rid of it in lieu of ap_queue_term().

-aaron