Logo AND Algorithmique Numérique Distribuée

Public GIT Repository
Fix a race condition in _XBT_LOG_ISENABLEDV().
authorArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Wed, 8 Feb 2012 16:03:36 +0000 (17:03 +0100)
committerArnaud Giersch <arnaud.giersch@iut-bm.univ-fcomte.fr>
Wed, 8 Feb 2012 16:04:06 +0000 (17:04 +0100)
Without this change, catv.threshold can be initialized by another
thread, between the test for priority being great enough, and
that for catv.threshold being initialized, leading to a false
positive answer.

Hypothesis
==========
  Initially, catv.threshold == xbt_log_priority_unititialized == -1
  After initialization, priority < catv.threshold
  Two threads running _XBT_LOG_ISENABLEDV() for the same
  category, and the same priority.

Thread A                                Thread B
========                                ========

                                        priority >= cat.threshold
                                          is TRUE
priority >= catv.threshold
  is TRUE

catv.threshold != x.l.p._uninitialized
  is FALSE

call xbt_log_cat_init(...)
  returns FALSE
                                        catv.threshold != x.l.p._uninitialized
                                          is TRUE

=> _XBT_LOG_ISENABLEDV(...)             => _XBT_LOG_ISENABLEDV(...)
     is FALSE                                is TRUE

include/xbt/log.h

index 5df2d07..ad7e612 100644 (file)
@@ -365,9 +365,9 @@ extern xbt_log_layout_t xbt_log_default_layout;
  */
 #define _XBT_LOG_ISENABLEDV(catv, priority)                  \
        (priority >= XBT_LOG_STATIC_THRESHOLD                 \
-        && priority >= catv.threshold                         \
         && (catv.threshold != xbt_log_priority_uninitialized \
-            || _xbt_log_cat_init(&catv, priority)) )
+            || _xbt_log_cat_init(&catv, priority))           \
+        && priority >= catv.threshold)
 
 /*
  * Internal Macros