Greg Ames wrote:
+ /* Atomically decrement the idle worker count */
+ for (;;) {
+ apr_uint32_t prev_idlers = queue_info->idlers;
+ if (apr_atomic_cas(&(queue_info->idlers), prev_idlers - 1, prev_idlers)
+ == prev_idlers) {
+ break;
+ }
apr_atomic_dec? That does return something.
The problem is that, since we have to use apr_atomic_cas for the increment (due to the lack of a return value on apr_atomic_inc), we can't use apr_atomic_dec on the same variable. apr_atomic_cas works on apr_uint32_t, while apr_atomic_dec works on apr_atomic_t. If we could change the apr_atomic_inc/dec functions to use apr_uint32_t, this part of the fdqueue code could become a lot simpler.
I still have one more change I'm hoping to make in the fdqueue synchronization logic: move the queue manipulation code in ap_queue_push/pop outside the mutex protected region by maintaining a linked list of queue nodes with apr_atomic_casptr. We won't be able to eliminate the mutex entirely, because it's needed for the condition variable, but moving the queue update code outside the critical region should at least help reduce the mutex contention.
Brian
