rbb         99/02/19 12:33:25

  Modified:    pthreads/src/include fdqueue.h
               pthreads/src/main fdqueue.c http_main.c
  Log:
  Fixes annoying fdqueue logic bug.  It used to be that if long lived 
connections
  used up all of your threads, any new connections to the same process would
  starve, because the worker threads were all busy.  Now, any process waits as
  soon as all of it's worker threads are not idle.  This keeps us from accepting
  quite as many connections, but now the ones we do accept will be served in a
  reasonable amount of time, no matter how long lived the previous requests 
were.
  
  Revision  Changes    Path
  1.3       +2 -0      apache-apr/pthreads/src/include/fdqueue.h
  
  Index: fdqueue.h
  ===================================================================
  RCS file: /home/cvs/apache-apr/pthreads/src/include/fdqueue.h,v
  retrieving revision 1.2
  retrieving revision 1.3
  diff -u -r1.2 -r1.3
  --- fdqueue.h 1999/02/12 18:30:19     1.2
  +++ fdqueue.h 1999/02/19 20:33:21     1.3
  @@ -23,6 +23,7 @@
       int tail;
       FDQueueElement *data;
       int bounds;
  +    int blanks;
       pthread_mutex_t one_big_mutex;
       pthread_cond_t not_empty;
       pthread_cond_t not_full;
  @@ -33,5 +34,6 @@
   int queue_push(FDQueue *queue, int fd, struct sockaddr *addr);
   int queue_pop(FDQueue *queue, struct sockaddr *addr);
   int queue_size(FDQueue *queue);
  +int increase_blanks(FDQueue *queue);
   
   #endif /* FDQUEUE_H */
  
  
  
  1.7       +23 -10    apache-apr/pthreads/src/main/fdqueue.c
  
  Index: fdqueue.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/pthreads/src/main/fdqueue.c,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- fdqueue.c 1999/02/15 21:58:58     1.6
  +++ fdqueue.c 1999/02/19 20:33:22     1.7
  @@ -11,6 +11,7 @@
       queue->head = queue->tail = 0;
       queue->data = ap_palloc(a, (++bounds) * sizeof(FDQueueElement));
       queue->bounds = bounds;
  +    queue->blanks = bounds - 1;
       ap_register_cleanup(a, queue, (void (*)(void *))queue_destroy, 
ap_null_cleanup);
       for (i=0; i < bounds; ++i)
           queue->data[i].fd = -1;
  @@ -28,20 +29,21 @@
       if (pthread_mutex_lock(&queue->one_big_mutex) != 0) {
           return FD_QUEUE_FAILURE;
       }
  -    while (queue->head == ((queue->tail + 1) % queue->bounds)) {
  -        pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
  -    }
       queue->data[queue->tail].fd = fd;
       queue->data[queue->tail].addr = *addr;
  -    /* If the queue was empty, signal that it no longer is */
  -    if (queue->head == queue->tail) {
  +    /* If the queue was empty, signal that it no longer is.  We use
  +       bounds-1 because of annoying allocation logic. */
  +    if (queue->blanks >= queue->bounds - 1) {
           pthread_cond_signal(&queue->not_empty);
       }
       queue->tail = (queue->tail + 1) % queue->bounds;
  +    queue->blanks--;
  +    if (queue->blanks == 0) {
  +        pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
  +    }
       if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
           return FD_QUEUE_FAILURE;
       }
  -    return FD_QUEUE_SUCCESS;
   }
   
   int queue_pop(FDQueue *queue, struct sockaddr *addr) {
  @@ -49,7 +51,7 @@
       if (pthread_mutex_lock(&queue->one_big_mutex) != 0) {
           return FD_QUEUE_FAILURE;
       }
  -    if (queue->head == queue->tail) {
  +    if (queue->blanks >= queue->bounds - 1) {
           pthread_cond_wait(&queue->not_empty, &queue->one_big_mutex);
       } 
       
  @@ -57,14 +59,25 @@
       *addr = queue->data[queue->head].addr;
       queue->data[queue->head].fd = -1;
       /* If the queue was full, signal that it no longer is */
  -    if (queue->head == ((queue->tail + 1) % queue->bounds)) {
  -        pthread_cond_signal(&queue->not_full);
  -    }
       queue->head = (queue->head + 1) % queue->bounds;
       if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
           return FD_QUEUE_FAILURE;
       }
       return fd;
  +}
  +
  +int increase_blanks(FDQueue *queue) {
  +    if (pthread_mutex_lock(&queue->one_big_mutex) != 0) {
  +        return FD_QUEUE_FAILURE;
  +    }
  +    if (queue->blanks == 0) {
  +        pthread_cond_signal(&queue->not_full);
  +    }
  +    queue->blanks++;
  +    if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
  +        return FD_QUEUE_FAILURE;
  +    }
  +    return FD_QUEUE_SUCCESS;
   }
   
   int queue_size(FDQueue *queue) {
  
  
  
  1.49      +2 -1      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.48
  retrieving revision 1.49
  diff -u -r1.48 -r1.49
  --- http_main.c       1999/02/18 18:40:54     1.48
  +++ http_main.c       1999/02/19 20:33:23     1.49
  @@ -2309,7 +2309,8 @@
           csd = queue_pop(&csd_queue, &sa_client);
        if (csd >= 0) {
            process_socket(ptrans, &sa_client, csd, my_pid, my_tid);
  -     } 
  +         increase_blanks(&csd_queue);
  +        } 
        ap_clear_pool(ptrans);
       }
       ap_destroy_pool(ptrans);
  
  
  

Reply via email to