From: Aaron Bannert Date: Fri, 26 Apr 2002 17:13:51 +0000 (+0000) Subject: Convert the worker MPM's fdqueue from a LIFO back into a FIFO. Since X-Git-Tag: 2.0.36~72 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=77adcc0737fa72d6c7a313976e31f287716ec85a;p=apache Convert the worker MPM's fdqueue from a LIFO back into a FIFO. Since elements in the queue represent accept()ed connections, we want them to be processed in the order that they were received. (I erroneously converted it to a LIFO quite awhile ago in the hopes that it would improve cache efficiency.) Remember to perform a make clean in the worker directory after this patch, since this patch changes the size of the fd_queue_t object (which is allocated in worker.c). git-svn-id: https://svn.apache.org/repos/asf/httpd/httpd/trunk@94813 13f79535-47bb-0310-9956-ffa450edef68 --- diff --git a/server/mpm/worker/fdqueue.c b/server/mpm/worker/fdqueue.c index c1fdef08dd..cc9acb3eab 100644 --- a/server/mpm/worker/fdqueue.c +++ b/server/mpm/worker/fdqueue.c @@ -62,13 +62,13 @@ * Detects when the fd_queue_t is full. This utility function is expected * to be called from within critical sections, and is not threadsafe. */ -#define ap_queue_full(queue) ((queue)->tail == (queue)->bounds) +#define ap_queue_full(queue) ((queue)->nelts == (queue)->bounds) /** * Detects when the fd_queue_t is empty. This utility function is expected * to be called from within critical sections, and is not threadsafe. */ -#define ap_queue_empty(queue) ((queue)->tail == 0) +#define ap_queue_empty(queue) ((queue)->nelts == 0) /** * Callback routine that is called to destroy this @@ -107,9 +107,10 @@ apr_status_t ap_queue_init(fd_queue_t *queue, int queue_capacity, apr_pool_t *a) return rv; } - queue->tail = 0; + queue->head = queue->tail = 0; queue->data = apr_palloc(a, queue_capacity * sizeof(fd_queue_elem_t)); queue->bounds = queue_capacity; + queue->nelts = 0; /* Set all the sockets in the queue to NULL */ for (i = 0; i < queue_capacity; ++i) @@ -146,9 +147,11 @@ apr_status_t ap_queue_push(fd_queue_t *queue, apr_socket_t *sd, apr_pool_t *p, apr_thread_cond_wait(queue->not_full, queue->one_big_mutex); } - elem = &queue->data[queue->tail++]; + elem = &queue->data[queue->tail]; + queue->tail = (queue->tail + 1) % queue->bounds; elem->sd = sd; elem->p = p; + queue->nelts++; if (queue->num_recycled != 0) { *recycled_pool = queue->recycled_pools[--queue->num_recycled]; @@ -209,15 +212,17 @@ apr_status_t ap_queue_pop(fd_queue_t *queue, apr_socket_t **sd, apr_pool_t **p, } } } - - elem = &queue->data[--queue->tail]; + + elem = &queue->data[queue->head]; + queue->head = (queue->head + 1) % queue->bounds; *sd = elem->sd; *p = elem->p; elem->sd = NULL; elem->p = NULL; + queue->nelts--; /* signal not_full if we were full before this pop */ - if (queue->tail == queue->bounds - 1) { + if (queue->nelts == queue->bounds - 1) { apr_thread_cond_signal(queue->not_full); } diff --git a/server/mpm/worker/fdqueue.h b/server/mpm/worker/fdqueue.h index 094cb2b35a..cdd306100a 100644 --- a/server/mpm/worker/fdqueue.h +++ b/server/mpm/worker/fdqueue.h @@ -78,8 +78,10 @@ struct fd_queue_elem_t { typedef struct fd_queue_elem_t fd_queue_elem_t; struct fd_queue_t { + int head; int tail; fd_queue_elem_t *data; + int nelts; int bounds; apr_thread_mutex_t *one_big_mutex; apr_thread_cond_t *not_empty;