I have been developing an application using apache 2.2 on linux 2.6. My test
environment creates a very heavy workload and puts a strain on every thing.
I would get good performance for a while and as the load ramped up, performance
would quickly get very bad. Erratically, transactions would finish quickly or
take a very long time -- tcpdump analysis showed millisecond or seconds between
responses. Also, the recv queue got very large.
I noticed that ap_queue_pop removes elements from the queue LIFO rather than
FIFO. Also noticed that apr_queue_pop uses a different technique which is not
too expensive and is fifo, so I changed ap_queue/pop/push to use that technique
and the receive problems went away.
snippet from ap_queue_pop (push is similar with appropriate changes to the
fd_queue_t struct)
AP_DEBUG_ASSERT(!queue->terminated);
#if 1
ap_assert(!ap_queue_full(queue)); /* we'd never expect the queue to be
full, so for debug, we check */
#else
AP_DEBUG_ASSERT(!ap_queue_full(queue));
#endif
#if 1
elem = &queue->data[queue->in];
queue->in = (queue->in + 1) % queue->bounds;
#else
elem = &queue->data[queue->nelts];
#endif
elem->sd = sd;
elem->cs = cs;
elem->p = p;
queue->nelts++;
Please let me know if you think this change is appropriate and/or if you'd like
more data
Jim Van Fleet