httpd-dev mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From Tianwei <>
Subject Is that a race condition bug?
Date Thu, 04 Feb 2010 06:42:40 GMT
Hi, httpd developers:
   I am using a
tool( to
study the potential race condition bugs in httpd.
I use httpd-2.2.14, and configure with --mpm=worker. For my first
round of testing, it actually reports lots of warning.  I am checking
one by one manually.  I have analyzed one of the bugs carefully, and
do not know if we should classify it as a benign race or not.
waring description:
1. I enable the USE_ATOMICS_GENERIC where use the hash lock to protect
the apr_atomic_casptr
2. The bug report is:
==5876== WARNING: Possible data race during write of size 8 at 0x429C578: {{{
==5876==    T2 (locks held: {L1}):
==5876==     #0  apr_atomic_casptr
==5876==     #1  ap_queue_info_set_idle
==5876==     #2  worker_thread
==5876==     #3  dummy_worker
==5876==     #4  ThreadSanitizerStartThread
==5876==   Concurrent read(s) happened at (OR AFTER) these points:
==5876==    T22 (locks held: {}):
==5876==     #0  ap_queue_info_wait_for_idler
==5876==     #1  listener_thread
==5876==     #2  dummy_worker
==5876==     #3  ThreadSanitizerStartThread

3. warning analysis.
    listener thread:
           apr_status_t ap_queue_info_wait_for_idler(fd_queue_info_t
                                          apr_pool_t **recycled_pool)

   /* Block if the count of idle workers is zero */
    if (queue_info->idlers == 0) {
        rv = apr_thread_mutex_lock(queue_info->idlers_mutex);
       while (queue_info->idlers == 0) {
            rv = apr_thread_cond_wait(queue_info->wait_for_idler,
     rv = apr_thread_mutex_unlock(queue_info->idlers_mutex);


   for (;;) {
      struct recycled_pool *first_pool = queue_info->recycled_pools;

   worker thread:
      apr_status_t ap_queue_info_set_idle(fd_queue_info_t *queue_info,
                                    apr_pool_t *pool_to_recycle)
    for (;;) {
            //new_recycle->next = queue_info->recycled_pools;
            struct recycled_pool *next = queue_info->recycled_pools;
            new_recycle->next = next;
            if (apr_atomic_casptr((volatile
                                  new_recycle, next) ==
                next) {
   /* If this thread just made the idle worker count nonzero,
     * wake up the listener. */
    if (prev_idlers == 0) {
        rv = apr_thread_mutex_lock(queue_info->idlers_mutex);
        if (rv != APR_SUCCESS) {
            return rv;
        rv = apr_thread_cond_signal(queue_info->wait_for_idler);
        if (rv != APR_SUCCESS) {
            return rv;
        rv = apr_thread_mutex_unlock(queue_info->idlers_mutex);
        if (rv != APR_SUCCESS) {
            return rv;

   if in listener thread, the queue_info->idlers  is "4", where it
will skip the "queue_info->idlers == 0" condition in
ap_queue_info_wait_for_idler, and decrease the idlers atomically, then
it will read "queue_info->recycled_pools". Then in worker thread, it
will write the "queue_info->recycled_pools" in apr_atomic_casptr with
a lock.
We can see that since the listener thread no longer execute the "lock,
cond_wait, unlock", even the worker thread will have a pthread_signal,
there is
no happen-before relation between the read of
"queue_info->recycled_pools" and the write of
"queue_info->recycled_pools". According to the definition, there is a
race condition here.

   According to analysis above, it seems that there is a race,
however, I am guessing the developer do not treat it as a problem, or
there is other unknown mechanism for me to protect this code? Can you
give me some suggestions?


Sheng, Tianwei
Inst. of High Performance Computing
Dept. of Computer Sci. & Tech.
Tsinghua Univ.

View raw message