You are viewing a plain text version of this content. The canonical link for it is here.
Posted to cvs@httpd.apache.org by rb...@hyperreal.org on 1999/02/23 20:11:23 UTC

cvs commit: apache-apr/pthreads/src/main fdqueue.c http_core.c http_main.c

rbb         99/02/23 11:11:23

  Modified:    pthreads/src/include fdqueue.h http_conf_globals.h
               pthreads/src/main fdqueue.c http_core.c http_main.c
  Log:
  A hopefully final commit for the fdqueue logic.  This removes the bug
  where our queue head and tail where getting out of joint because of
  threads coming out of wait state without being signaled.  This is allowed
  by the pthreads spec, but we have to code so our program doesn't do bad
  things when it happens.
  
  As a part of this patch, we are allowing users to determine how much
  overflow their fdqueue will handle.  Basically, our queue size is
  # of worker threads + user defined overcommit.  If the overcommit is
  less than or equal to # of accept threads, we bump it up to accept threads.
  This is to make sure we always have enough space for any acceptors that
  may get a connection after our queue is supposed to be full.
  
  Revision  Changes    Path
  1.6       +3 -1      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.5
  retrieving revision 1.6
  diff -u -r1.5 -r1.6
  --- fdqueue.h	1999/02/22 20:05:45	1.5
  +++ fdqueue.h	1999/02/23 19:11:18	1.6
  @@ -29,11 +29,13 @@
       pthread_cond_t not_full;
   } FDQueue;
   
  -int queue_init(FDQueue *queue, size_t bounds, pool *a);
  +int queue_init(FDQueue *queue, int regular, int overflow, pool *a);
   void *queue_destroy(FDQueue *queue);
   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);
  +int queue_full(FDQueue *queue);
  +int block_on_queue(FDQueue *queue);
   
   #endif /* FDQUEUE_H */
  
  
  
  1.7       +1 -0      apache-apr/pthreads/src/include/http_conf_globals.h
  
  Index: http_conf_globals.h
  ===================================================================
  RCS file: /home/cvs/apache-apr/pthreads/src/include/http_conf_globals.h,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- http_conf_globals.h	1999/02/15 20:38:54	1.6
  +++ http_conf_globals.h	1999/02/23 19:11:19	1.7
  @@ -75,6 +75,7 @@
   #endif
   extern int ap_threads_per_child;
   extern int ap_acceptors_per_child;
  +extern int ap_overflow;
   extern int ap_idle_thread_threshold;
   extern int ap_busy_thread_threshold;
   extern int ap_max_requests_per_child;
  
  
  
  1.11      +23 -16    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.10
  retrieving revision 1.11
  diff -u -r1.10 -r1.11
  --- fdqueue.c	1999/02/22 20:05:46	1.10
  +++ fdqueue.c	1999/02/23 19:11:21	1.11
  @@ -3,15 +3,16 @@
   /* Assumption: queue itself is allocated by the user */
   /* Assumption: increment and decrement are atomic on int */
   
  -int queue_init(FDQueue *queue, size_t bounds, pool *a) {
  +int queue_init(FDQueue *queue, int regular, int overflow, pool *a) {
       int i;
  +    int bounds = regular + overflow + 1;
       pthread_mutex_init(&queue->one_big_mutex, NULL);
       pthread_cond_init(&queue->not_empty, NULL);
       pthread_cond_init(&queue->not_full, NULL);
       queue->head = queue->tail = 0;
  -    queue->data = ap_palloc(a, (++bounds) * sizeof(FDQueueElement));
  +    queue->data = ap_palloc(a, bounds * sizeof(FDQueueElement));
       queue->bounds = bounds;
  -    queue->blanks = bounds - 1;
  +    queue->blanks = regular;
       ap_register_cleanup(a, queue, (void (*)(void *))queue_destroy, ap_null_cleanup);
       for (i=0; i < bounds; ++i)
           queue->data[i].fd = -1;
  @@ -34,7 +35,7 @@
       queue->tail = (queue->tail + 1) % queue->bounds;
       queue->blanks--;
       pthread_cond_signal(&queue->not_empty);
  -    if (queue->blanks == 0) {
  +    if (queue->head == (queue->tail + 1) % queue->bounds) {
           pthread_cond_wait(&queue->not_full, &queue->one_big_mutex);
       }
       if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
  @@ -47,35 +48,41 @@
       if (pthread_mutex_lock(&queue->one_big_mutex) != 0) {
           return FD_QUEUE_FAILURE;
       }
  -    if (queue->blanks >= queue->bounds - 1) {
  +    if (queue->blanks > 0) {
  +        pthread_cond_signal(&queue->not_full);
  +    }
  +    if (queue->head == queue->tail) {
           pthread_cond_wait(&queue->not_empty, &queue->one_big_mutex);
       } 
       
       fd = queue->data[queue->head].fd;
       *addr = queue->data[queue->head].addr;
       queue->data[queue->head].fd = -1;
  -    /* If the queue was full, signal that it no longer is */
  -    queue->head = (queue->head + 1) % queue->bounds;
  +    if (fd != -1) {
  +        queue->head = (queue->head + 1) % queue->bounds;
  +        queue->blanks++;
  +    }
       if (pthread_mutex_unlock(&queue->one_big_mutex) != 0) {
           return FD_QUEUE_FAILURE;
       }
       return fd;
   }
  +
  +int queue_size(FDQueue *queue) {
  +    return ((queue->tail - queue->head + queue->bounds) % queue->bounds);
  +}
   
  -int increase_blanks(FDQueue *queue) {
  +int queue_full(FDQueue *queue) {
  +    return(queue->blanks <= 0);
  +}
  +
  +int block_on_queue(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++;
  +    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_size(FDQueue *queue) {
  -    return ((queue->tail - queue->head + queue->bounds) % queue->bounds);
  -}
  
  
  
  1.7       +13 -0     apache-apr/pthreads/src/main/http_core.c
  
  Index: http_core.c
  ===================================================================
  RCS file: /home/cvs/apache-apr/pthreads/src/main/http_core.c,v
  retrieving revision 1.6
  retrieving revision 1.7
  diff -u -r1.6 -r1.7
  --- http_core.c	1999/02/11 16:33:04	1.6
  +++ http_core.c	1999/02/23 19:11:21	1.7
  @@ -2205,6 +2205,17 @@
       return NULL;
   }
   
  +static const char *set_overflow(cmd_parms *cmd, void * dummy, char *arg)
  +{
  +    const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
  +    if (err != NULL) {
  +        return err;
  +    }
  +    ap_overflow = atoi(arg);
  + 
  +    return NULL;
  +}
  +
   static const char *set_max_requests(cmd_parms *cmd, void *dummy, char *arg) 
   {
       const char *err = ap_check_cmd_context(cmd, GLOBAL_ONLY);
  @@ -2838,6 +2849,8 @@
     "Maximum number of idle children" },
   { "MaxServers", set_max_free_servers, NULL, RSRC_CONF, TAKE1,
     "Deprecated equivalent to MaxSpareServers" },
  +{ "ExcessWorkers", set_overflow, NULL, RSRC_CONF, TAKE1,
  +  "Number of connections to accept beyond the number of threads per child."},
   { "IdleThreadThreshold", set_idle_threshold, NULL, RSRC_CONF, TAKE1,
     "Minimum number of idle threads, below which process is considered ready for reaping." },
   { "BusyThreadThreshold", set_busy_threshold, NULL, RSRC_CONF, TAKE1,
  
  
  
  1.53      +21 -5     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.52
  retrieving revision 1.53
  diff -u -r1.52 -r1.53
  --- http_main.c	1999/02/22 20:05:46	1.52
  +++ http_main.c	1999/02/23 19:11:21	1.53
  @@ -158,6 +158,7 @@
   #endif
   int ap_threads_per_child;
   int ap_acceptors_per_child;
  +int ap_overflow = 0;
   int ap_max_requests_per_child;
   int ap_idle_thread_threshold;
   int ap_busy_thread_threshold;
  @@ -2343,9 +2344,16 @@
   				    (request_rec *) NULL);
   	/* lock around the accept if necessary */
   	SAFE_ACCEPT(accept_mutex_on(my_tid - ap_threads_per_child));
  -        csd = accept(sd, &sa_client, &len);
  -	SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child));
  -	(void) ap_update_child_status(my_pid, my_tid, SERVER_QUEUEING, 
  +        if (queue_full(&csd_queue)) {
  +            SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child));
  +            block_on_queue(&csd_queue);
  +            csd = -1;
  +        }
  +        else {
  +            csd = accept(sd, &sa_client, &len);
  +	    SAFE_ACCEPT(accept_mutex_off(my_tid - ap_threads_per_child));
  +	}
  +        (void) ap_update_child_status(my_pid, my_tid, SERVER_QUEUEING, 
   				      (request_rec *) NULL);
   	if (csd >= 0) {
   	    if (queue_push(&csd_queue, csd, &sa_client) != 0) {
  @@ -2379,7 +2387,7 @@
           csd = queue_pop(&csd_queue, &sa_client);
   	if (csd >= 0) {
   	    process_socket(ptrans, &sa_client, csd, my_pid, my_tid);
  -	    increase_blanks(&csd_queue);
  +	    /*increase_blanks(&csd_queue);*/
           } 
   	ap_clear_pool(ptrans);
       }
  @@ -2601,6 +2609,7 @@
       sigset_t sig_mask;
       int signal_received;
       pthread_t thread;
  +    int temp = 0;
   
       my_pid = getpid();
       requests_this_child = ap_max_requests_per_child;
  @@ -2636,8 +2645,15 @@
       if (pthread_sigmask(SIG_SETMASK, &sig_mask, NULL) != 0) {
           ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf, "pthread_sigmask");
       }
  +
  +    if (ap_overflow < ap_acceptors_per_child)
  +        ap_overflow = ap_acceptors_per_child;
  +    else if (ap_overflow > ap_acceptors_per_child) {
  +        temp = ap_overflow - ap_acceptors_per_child;
  +        ap_overflow -= ap_acceptors_per_child;
  +    }
   
  -    queue_init(&csd_queue, ap_threads_per_child, pchild);
  +    queue_init(&csd_queue, ap_threads_per_child + temp, ap_overflow, pchild);
   
       if (pthread_create(&thread, NULL, thread_starter_thread, &child_num_arg)) {
           ap_log_error(APLOG_MARK, APLOG_ALERT, server_conf,