Home | History | Annotate | Line # | Download | only in docs
ThreadSafetyAnalysis.rst revision 1.1
      1  1.1  joerg 
      2  1.1  joerg ======================
      3  1.1  joerg Thread Safety Analysis
      4  1.1  joerg ======================
      5  1.1  joerg 
      6  1.1  joerg Introduction
      7  1.1  joerg ============
      8  1.1  joerg 
      9  1.1  joerg Clang Thread Safety Analysis is a C++ language extension which warns about
     10  1.1  joerg potential race conditions in code.  The analysis is completely static (i.e.
     11  1.1  joerg compile-time); there is no run-time overhead.  The analysis is still
     12  1.1  joerg under active development, but it is mature enough to be deployed in an
     13  1.1  joerg industrial setting.  It is being developed by Google, in collaboration with
     14  1.1  joerg CERT/SEI, and is used extensively in Google's internal code base.
     15  1.1  joerg 
     16  1.1  joerg Thread safety analysis works very much like a type system for multi-threaded
     17  1.1  joerg programs.  In addition to declaring the *type* of data (e.g. ``int``, ``float``,
     18  1.1  joerg etc.), the programmer can (optionally) declare how access to that data is
     19  1.1  joerg controlled in a multi-threaded environment.  For example, if ``foo`` is
     20  1.1  joerg *guarded by* the mutex ``mu``, then the analysis will issue a warning whenever
     21  1.1  joerg a piece of code reads or writes to ``foo`` without first locking ``mu``.
     22  1.1  joerg Similarly, if there are particular routines that should only be called by
     23  1.1  joerg the GUI thread, then the analysis will warn if other threads call those
     24  1.1  joerg routines.
     25  1.1  joerg 
     26  1.1  joerg Getting Started
     27  1.1  joerg ----------------
     28  1.1  joerg 
     29  1.1  joerg .. code-block:: c++
     30  1.1  joerg 
     31  1.1  joerg   #include "mutex.h"
     32  1.1  joerg 
     33  1.1  joerg   class BankAccount {
     34  1.1  joerg   private:
     35  1.1  joerg     Mutex mu;
     36  1.1  joerg     int   balance GUARDED_BY(mu);
     37  1.1  joerg 
     38  1.1  joerg     void depositImpl(int amount) {
     39  1.1  joerg       balance += amount;       // WARNING! Cannot write balance without locking mu.
     40  1.1  joerg     }
     41  1.1  joerg 
     42  1.1  joerg     void withdrawImpl(int amount) REQUIRES(mu) {
     43  1.1  joerg       balance -= amount;       // OK. Caller must have locked mu.
     44  1.1  joerg     }
     45  1.1  joerg 
     46  1.1  joerg   public:
     47  1.1  joerg     void withdraw(int amount) {
     48  1.1  joerg       mu.Lock();
     49  1.1  joerg       withdrawImpl(amount);    // OK.  We've locked mu.
     50  1.1  joerg     }                          // WARNING!  Failed to unlock mu.
     51  1.1  joerg 
     52  1.1  joerg     void transferFrom(BankAccount& b, int amount) {
     53  1.1  joerg       mu.Lock();
     54  1.1  joerg       b.withdrawImpl(amount);  // WARNING!  Calling withdrawImpl() requires locking b.mu.
     55  1.1  joerg       depositImpl(amount);     // OK.  depositImpl() has no requirements.
     56  1.1  joerg       mu.Unlock();
     57  1.1  joerg     }
     58  1.1  joerg   };
     59  1.1  joerg 
     60  1.1  joerg This example demonstrates the basic concepts behind the analysis.  The
     61  1.1  joerg ``GUARDED_BY`` attribute declares that a thread must lock ``mu`` before it can
     62  1.1  joerg read or write to ``balance``, thus ensuring that the increment and decrement
     63  1.1  joerg operations are atomic.  Similarly, ``REQUIRES`` declares that
     64  1.1  joerg the calling thread must lock ``mu`` before calling ``withdrawImpl``.
     65  1.1  joerg Because the caller is assumed to have locked ``mu``, it is safe to modify
     66  1.1  joerg ``balance`` within the body of the method.
     67  1.1  joerg 
     68  1.1  joerg The ``depositImpl()`` method does not have ``REQUIRES``, so the
     69  1.1  joerg analysis issues a warning.  Thread safety analysis is not inter-procedural, so
     70  1.1  joerg caller requirements must be explicitly declared.
     71  1.1  joerg There is also a warning in ``transferFrom()``, because although the method
     72  1.1  joerg locks ``this->mu``, it does not lock ``b.mu``.  The analysis understands
     73  1.1  joerg that these are two separate mutexes, in two different objects.
     74  1.1  joerg 
     75  1.1  joerg Finally, there is a warning in the ``withdraw()`` method, because it fails to
     76  1.1  joerg unlock ``mu``.  Every lock must have a corresponding unlock, and the analysis
     77  1.1  joerg will detect both double locks, and double unlocks.  A function is allowed to
     78  1.1  joerg acquire a lock without releasing it, (or vice versa), but it must be annotated
     79  1.1  joerg as such (using ``ACQUIRE``/``RELEASE``).
     80  1.1  joerg 
     81  1.1  joerg 
     82  1.1  joerg Running The Analysis
     83  1.1  joerg --------------------
     84  1.1  joerg 
     85  1.1  joerg To run the analysis, simply compile with the ``-Wthread-safety`` flag, e.g.
     86  1.1  joerg 
     87  1.1  joerg .. code-block:: bash
     88  1.1  joerg 
     89  1.1  joerg   clang -c -Wthread-safety example.cpp
     90  1.1  joerg 
     91  1.1  joerg Note that this example assumes the presence of a suitably annotated
     92  1.1  joerg :ref:`mutexheader` that declares which methods perform locking,
     93  1.1  joerg unlocking, and so on.
     94  1.1  joerg 
     95  1.1  joerg 
     96  1.1  joerg Basic Concepts: Capabilities
     97  1.1  joerg ============================
     98  1.1  joerg 
     99  1.1  joerg Thread safety analysis provides a way of protecting *resources* with
    100  1.1  joerg *capabilities*.  A resource is either a data member, or a function/method
    101  1.1  joerg that provides access to some underlying resource.  The analysis ensures that
    102  1.1  joerg the calling thread cannot access the *resource* (i.e. call the function, or
    103  1.1  joerg read/write the data) unless it has the *capability* to do so.
    104  1.1  joerg 
    105  1.1  joerg Capabilities are associated with named C++ objects which declare specific
    106  1.1  joerg methods to acquire and release the capability.  The name of the object serves
    107  1.1  joerg to identify the capability.  The most common example is a mutex.  For example,
    108  1.1  joerg if ``mu`` is a mutex, then calling ``mu.Lock()`` causes the calling thread
    109  1.1  joerg to acquire the capability to access data that is protected by ``mu``. Similarly,
    110  1.1  joerg calling ``mu.Unlock()`` releases that capability.
    111  1.1  joerg 
    112  1.1  joerg A thread may hold a capability either *exclusively* or *shared*.  An exclusive
    113  1.1  joerg capability can be held by only one thread at a time, while a shared capability
    114  1.1  joerg can be held by many threads at the same time.  This mechanism enforces a
    115  1.1  joerg multiple-reader, single-writer pattern.  Write operations to protected data
    116  1.1  joerg require exclusive access, while read operations require only shared access.
    117  1.1  joerg 
    118  1.1  joerg At any given moment during program execution, a thread holds a specific set of
    119  1.1  joerg capabilities (e.g. the set of mutexes that it has locked.)  These act like keys
    120  1.1  joerg or tokens that allow the thread to access a given resource.  Just like physical
    121  1.1  joerg security keys, a thread cannot make copy of a capability, nor can it destroy
    122  1.1  joerg one.  A thread can only release a capability to another thread, or acquire one
    123  1.1  joerg from another thread.  The annotations are deliberately agnostic about the
    124  1.1  joerg exact mechanism used to acquire and release capabilities; it assumes that the
    125  1.1  joerg underlying implementation (e.g. the Mutex implementation) does the handoff in
    126  1.1  joerg an appropriate manner.
    127  1.1  joerg 
    128  1.1  joerg The set of capabilities that are actually held by a given thread at a given
    129  1.1  joerg point in program execution is a run-time concept.  The static analysis works
    130  1.1  joerg by calculating an approximation of that set, called the *capability
    131  1.1  joerg environment*.  The capability environment is calculated for every program point,
    132  1.1  joerg and describes the set of capabilities that are statically known to be held, or
    133  1.1  joerg not held, at that particular point.  This environment is a conservative
    134  1.1  joerg approximation of the full set of capabilities that will actually held by a
    135  1.1  joerg thread at run-time.
    136  1.1  joerg 
    137  1.1  joerg 
    138  1.1  joerg Reference Guide
    139  1.1  joerg ===============
    140  1.1  joerg 
    141  1.1  joerg The thread safety analysis uses attributes to declare threading constraints.
    142  1.1  joerg Attributes must be attached to named declarations, such as classes, methods,
    143  1.1  joerg and data members. Users are *strongly advised* to define macros for the various
    144  1.1  joerg attributes; example definitions can be found in :ref:`mutexheader`, below.
    145  1.1  joerg The following documentation assumes the use of macros.
    146  1.1  joerg 
    147  1.1  joerg For historical reasons, prior versions of thread safety used macro names that
    148  1.1  joerg were very lock-centric.  These macros have since been renamed to fit a more
    149  1.1  joerg general capability model.  The prior names are still in use, and will be
    150  1.1  joerg mentioned under the tag *previously* where appropriate.
    151  1.1  joerg 
    152  1.1  joerg 
    153  1.1  joerg GUARDED_BY(c) and PT_GUARDED_BY(c)
    154  1.1  joerg ----------------------------------
    155  1.1  joerg 
    156  1.1  joerg ``GUARDED_BY`` is an attribute on data members, which declares that the data
    157  1.1  joerg member is protected by the given capability.  Read operations on the data
    158  1.1  joerg require shared access, while write operations require exclusive access.
    159  1.1  joerg 
    160  1.1  joerg ``PT_GUARDED_BY`` is similar, but is intended for use on pointers and smart
    161  1.1  joerg pointers. There is no constraint on the data member itself, but the *data that
    162  1.1  joerg it points to* is protected by the given capability.
    163  1.1  joerg 
    164  1.1  joerg .. code-block:: c++
    165  1.1  joerg 
    166  1.1  joerg   Mutex mu;
    167  1.1  joerg   int *p1             GUARDED_BY(mu);
    168  1.1  joerg   int *p2             PT_GUARDED_BY(mu);
    169  1.1  joerg   unique_ptr<int> p3  PT_GUARDED_BY(mu);
    170  1.1  joerg 
    171  1.1  joerg   void test() {
    172  1.1  joerg     p1 = 0;             // Warning!
    173  1.1  joerg 
    174  1.1  joerg     *p2 = 42;           // Warning!
    175  1.1  joerg     p2 = new int;       // OK.
    176  1.1  joerg 
    177  1.1  joerg     *p3 = 42;           // Warning!
    178  1.1  joerg     p3.reset(new int);  // OK.
    179  1.1  joerg   }
    180  1.1  joerg 
    181  1.1  joerg 
    182  1.1  joerg REQUIRES(...), REQUIRES_SHARED(...)
    183  1.1  joerg -----------------------------------
    184  1.1  joerg 
    185  1.1  joerg *Previously*: ``EXCLUSIVE_LOCKS_REQUIRED``, ``SHARED_LOCKS_REQUIRED``
    186  1.1  joerg 
    187  1.1  joerg ``REQUIRES`` is an attribute on functions or methods, which
    188  1.1  joerg declares that the calling thread must have exclusive access to the given
    189  1.1  joerg capabilities.  More than one capability may be specified.  The capabilities
    190  1.1  joerg must be held on entry to the function, *and must still be held on exit*.
    191  1.1  joerg 
    192  1.1  joerg ``REQUIRES_SHARED`` is similar, but requires only shared access.
    193  1.1  joerg 
    194  1.1  joerg .. code-block:: c++
    195  1.1  joerg 
    196  1.1  joerg   Mutex mu1, mu2;
    197  1.1  joerg   int a GUARDED_BY(mu1);
    198  1.1  joerg   int b GUARDED_BY(mu2);
    199  1.1  joerg 
    200  1.1  joerg   void foo() REQUIRES(mu1, mu2) {
    201  1.1  joerg     a = 0;
    202  1.1  joerg     b = 0;
    203  1.1  joerg   }
    204  1.1  joerg 
    205  1.1  joerg   void test() {
    206  1.1  joerg     mu1.Lock();
    207  1.1  joerg     foo();         // Warning!  Requires mu2.
    208  1.1  joerg     mu1.Unlock();
    209  1.1  joerg   }
    210  1.1  joerg 
    211  1.1  joerg 
    212  1.1  joerg ACQUIRE(...), ACQUIRE_SHARED(...), RELEASE(...), RELEASE_SHARED(...)
    213  1.1  joerg --------------------------------------------------------------------
    214  1.1  joerg 
    215  1.1  joerg *Previously*: ``EXCLUSIVE_LOCK_FUNCTION``, ``SHARED_LOCK_FUNCTION``,
    216  1.1  joerg ``UNLOCK_FUNCTION``
    217  1.1  joerg 
    218  1.1  joerg ``ACQUIRE`` is an attribute on functions or methods, which
    219  1.1  joerg declares that the function acquires a capability, but does not release it.  The
    220  1.1  joerg caller must not hold the given capability on entry, and it will hold the
    221  1.1  joerg capability on exit.  ``ACQUIRE_SHARED`` is similar.
    222  1.1  joerg 
    223  1.1  joerg ``RELEASE`` and ``RELEASE_SHARED`` declare that the function releases the given
    224  1.1  joerg capability.  The caller must hold the capability on entry, and will no longer
    225  1.1  joerg hold it on exit. It does not matter whether the given capability is shared or
    226  1.1  joerg exclusive.
    227  1.1  joerg 
    228  1.1  joerg .. code-block:: c++
    229  1.1  joerg 
    230  1.1  joerg   Mutex mu;
    231  1.1  joerg   MyClass myObject GUARDED_BY(mu);
    232  1.1  joerg 
    233  1.1  joerg   void lockAndInit() ACQUIRE(mu) {
    234  1.1  joerg     mu.Lock();
    235  1.1  joerg     myObject.init();
    236  1.1  joerg   }
    237  1.1  joerg 
    238  1.1  joerg   void cleanupAndUnlock() RELEASE(mu) {
    239  1.1  joerg     myObject.cleanup();
    240  1.1  joerg   }                          // Warning!  Need to unlock mu.
    241  1.1  joerg 
    242  1.1  joerg   void test() {
    243  1.1  joerg     lockAndInit();
    244  1.1  joerg     myObject.doSomething();
    245  1.1  joerg     cleanupAndUnlock();
    246  1.1  joerg     myObject.doSomething();  // Warning, mu is not locked.
    247  1.1  joerg   }
    248  1.1  joerg 
    249  1.1  joerg If no argument is passed to ``ACQUIRE`` or ``RELEASE``, then the argument is
    250  1.1  joerg assumed to be ``this``, and the analysis will not check the body of the
    251  1.1  joerg function.  This pattern is intended for use by classes which hide locking
    252  1.1  joerg details behind an abstract interface.  For example:
    253  1.1  joerg 
    254  1.1  joerg .. code-block:: c++
    255  1.1  joerg 
    256  1.1  joerg   template <class T>
    257  1.1  joerg   class CAPABILITY("mutex") Container {
    258  1.1  joerg   private:
    259  1.1  joerg     Mutex mu;
    260  1.1  joerg     T* data;
    261  1.1  joerg 
    262  1.1  joerg   public:
    263  1.1  joerg     // Hide mu from public interface.
    264  1.1  joerg     void Lock()   ACQUIRE() { mu.Lock(); }
    265  1.1  joerg     void Unlock() RELEASE() { mu.Unlock(); }
    266  1.1  joerg 
    267  1.1  joerg     T& getElem(int i) { return data[i]; }
    268  1.1  joerg   };
    269  1.1  joerg 
    270  1.1  joerg   void test() {
    271  1.1  joerg     Container<int> c;
    272  1.1  joerg     c.Lock();
    273  1.1  joerg     int i = c.getElem(0);
    274  1.1  joerg     c.Unlock();
    275  1.1  joerg   }
    276  1.1  joerg 
    277  1.1  joerg 
    278  1.1  joerg EXCLUDES(...)
    279  1.1  joerg -------------
    280  1.1  joerg 
    281  1.1  joerg *Previously*: ``LOCKS_EXCLUDED``
    282  1.1  joerg 
    283  1.1  joerg ``EXCLUDES`` is an attribute on functions or methods, which declares that
    284  1.1  joerg the caller must *not* hold the given capabilities.  This annotation is
    285  1.1  joerg used to prevent deadlock.  Many mutex implementations are not re-entrant, so
    286  1.1  joerg deadlock can occur if the function acquires the mutex a second time.
    287  1.1  joerg 
    288  1.1  joerg .. code-block:: c++
    289  1.1  joerg 
    290  1.1  joerg   Mutex mu;
    291  1.1  joerg   int a GUARDED_BY(mu);
    292  1.1  joerg 
    293  1.1  joerg   void clear() EXCLUDES(mu) {
    294  1.1  joerg     mu.Lock();
    295  1.1  joerg     a = 0;
    296  1.1  joerg     mu.Unlock();
    297  1.1  joerg   }
    298  1.1  joerg 
    299  1.1  joerg   void reset() {
    300  1.1  joerg     mu.Lock();
    301  1.1  joerg     clear();     // Warning!  Caller cannot hold 'mu'.
    302  1.1  joerg     mu.Unlock();
    303  1.1  joerg   }
    304  1.1  joerg 
    305  1.1  joerg Unlike ``REQUIRES``, ``EXCLUDES`` is optional.  The analysis will not issue a
    306  1.1  joerg warning if the attribute is missing, which can lead to false negatives in some
    307  1.1  joerg cases.  This issue is discussed further in :ref:`negative`.
    308  1.1  joerg 
    309  1.1  joerg 
    310  1.1  joerg NO_THREAD_SAFETY_ANALYSIS
    311  1.1  joerg -------------------------
    312  1.1  joerg 
    313  1.1  joerg ``NO_THREAD_SAFETY_ANALYSIS`` is an attribute on functions or methods, which
    314  1.1  joerg turns off thread safety checking for that method.  It provides an escape hatch
    315  1.1  joerg for functions which are either (1) deliberately thread-unsafe, or (2) are
    316  1.1  joerg thread-safe, but too complicated for the analysis to understand.  Reasons for
    317  1.1  joerg (2) will be described in the :ref:`limitations`, below.
    318  1.1  joerg 
    319  1.1  joerg .. code-block:: c++
    320  1.1  joerg 
    321  1.1  joerg   class Counter {
    322  1.1  joerg     Mutex mu;
    323  1.1  joerg     int a GUARDED_BY(mu);
    324  1.1  joerg 
    325  1.1  joerg     void unsafeIncrement() NO_THREAD_SAFETY_ANALYSIS { a++; }
    326  1.1  joerg   };
    327  1.1  joerg 
    328  1.1  joerg Unlike the other attributes, NO_THREAD_SAFETY_ANALYSIS is not part of the
    329  1.1  joerg interface of a function, and should thus be placed on the function definition
    330  1.1  joerg (in the ``.cc`` or ``.cpp`` file) rather than on the function declaration
    331  1.1  joerg (in the header).
    332  1.1  joerg 
    333  1.1  joerg 
    334  1.1  joerg RETURN_CAPABILITY(c)
    335  1.1  joerg --------------------
    336  1.1  joerg 
    337  1.1  joerg *Previously*: ``LOCK_RETURNED``
    338  1.1  joerg 
    339  1.1  joerg ``RETURN_CAPABILITY`` is an attribute on functions or methods, which declares
    340  1.1  joerg that the function returns a reference to the given capability.  It is used to
    341  1.1  joerg annotate getter methods that return mutexes.
    342  1.1  joerg 
    343  1.1  joerg .. code-block:: c++
    344  1.1  joerg 
    345  1.1  joerg   class MyClass {
    346  1.1  joerg   private:
    347  1.1  joerg     Mutex mu;
    348  1.1  joerg     int a GUARDED_BY(mu);
    349  1.1  joerg 
    350  1.1  joerg   public:
    351  1.1  joerg     Mutex* getMu() RETURN_CAPABILITY(mu) { return &mu; }
    352  1.1  joerg 
    353  1.1  joerg     // analysis knows that getMu() == mu
    354  1.1  joerg     void clear() REQUIRES(getMu()) { a = 0; }
    355  1.1  joerg   };
    356  1.1  joerg 
    357  1.1  joerg 
    358  1.1  joerg ACQUIRED_BEFORE(...), ACQUIRED_AFTER(...)
    359  1.1  joerg -----------------------------------------
    360  1.1  joerg 
    361  1.1  joerg ``ACQUIRED_BEFORE`` and ``ACQUIRED_AFTER`` are attributes on member
    362  1.1  joerg declarations, specifically declarations of mutexes or other capabilities.
    363  1.1  joerg These declarations enforce a particular order in which the mutexes must be
    364  1.1  joerg acquired, in order to prevent deadlock.
    365  1.1  joerg 
    366  1.1  joerg .. code-block:: c++
    367  1.1  joerg 
    368  1.1  joerg   Mutex m1;
    369  1.1  joerg   Mutex m2 ACQUIRED_AFTER(m1);
    370  1.1  joerg 
    371  1.1  joerg   // Alternative declaration
    372  1.1  joerg   // Mutex m2;
    373  1.1  joerg   // Mutex m1 ACQUIRED_BEFORE(m2);
    374  1.1  joerg 
    375  1.1  joerg   void foo() {
    376  1.1  joerg     m2.Lock();
    377  1.1  joerg     m1.Lock();  // Warning!  m2 must be acquired after m1.
    378  1.1  joerg     m1.Unlock();
    379  1.1  joerg     m2.Unlock();
    380  1.1  joerg   }
    381  1.1  joerg 
    382  1.1  joerg 
    383  1.1  joerg CAPABILITY(<string>)
    384  1.1  joerg --------------------
    385  1.1  joerg 
    386  1.1  joerg *Previously*: ``LOCKABLE``
    387  1.1  joerg 
    388  1.1  joerg ``CAPABILITY`` is an attribute on classes, which specifies that objects of the
    389  1.1  joerg class can be used as a capability.  The string argument specifies the kind of
    390  1.1  joerg capability in error messages, e.g. ``"mutex"``.  See the ``Container`` example
    391  1.1  joerg given above, or the ``Mutex`` class in :ref:`mutexheader`.
    392  1.1  joerg 
    393  1.1  joerg 
    394  1.1  joerg SCOPED_CAPABILITY
    395  1.1  joerg -----------------
    396  1.1  joerg 
    397  1.1  joerg *Previously*: ``SCOPED_LOCKABLE``
    398  1.1  joerg 
    399  1.1  joerg ``SCOPED_CAPABILITY`` is an attribute on classes that implement RAII-style
    400  1.1  joerg locking, in which a capability is acquired in the constructor, and released in
    401  1.1  joerg the destructor.  Such classes require special handling because the constructor
    402  1.1  joerg and destructor refer to the capability via different names; see the
    403  1.1  joerg ``MutexLocker`` class in :ref:`mutexheader`, below.
    404  1.1  joerg 
    405  1.1  joerg 
    406  1.1  joerg TRY_ACQUIRE(<bool>, ...), TRY_ACQUIRE_SHARED(<bool>, ...)
    407  1.1  joerg ---------------------------------------------------------
    408  1.1  joerg 
    409  1.1  joerg *Previously:* ``EXCLUSIVE_TRYLOCK_FUNCTION``, ``SHARED_TRYLOCK_FUNCTION``
    410  1.1  joerg 
    411  1.1  joerg These are attributes on a function or method that tries to acquire the given
    412  1.1  joerg capability, and returns a boolean value indicating success or failure.
    413  1.1  joerg The first argument must be ``true`` or ``false``, to specify which return value
    414  1.1  joerg indicates success, and the remaining arguments are interpreted in the same way
    415  1.1  joerg as ``ACQUIRE``.  See :ref:`mutexheader`, below, for example uses.
    416  1.1  joerg 
    417  1.1  joerg 
    418  1.1  joerg ASSERT_CAPABILITY(...) and ASSERT_SHARED_CAPABILITY(...)
    419  1.1  joerg --------------------------------------------------------
    420  1.1  joerg 
    421  1.1  joerg *Previously:*  ``ASSERT_EXCLUSIVE_LOCK``, ``ASSERT_SHARED_LOCK``
    422  1.1  joerg 
    423  1.1  joerg These are attributes on a function or method that does a run-time test to see
    424  1.1  joerg whether the calling thread holds the given capability.  The function is assumed
    425  1.1  joerg to fail (no return) if the capability is not held.  See :ref:`mutexheader`,
    426  1.1  joerg below, for example uses.
    427  1.1  joerg 
    428  1.1  joerg 
    429  1.1  joerg GUARDED_VAR and PT_GUARDED_VAR
    430  1.1  joerg ------------------------------
    431  1.1  joerg 
    432  1.1  joerg Use of these attributes has been deprecated.
    433  1.1  joerg 
    434  1.1  joerg 
    435  1.1  joerg Warning flags
    436  1.1  joerg -------------
    437  1.1  joerg 
    438  1.1  joerg * ``-Wthread-safety``:  Umbrella flag which turns on the following three:
    439  1.1  joerg 
    440  1.1  joerg   + ``-Wthread-safety-attributes``: Sanity checks on attribute syntax.
    441  1.1  joerg   + ``-Wthread-safety-analysis``: The core analysis.
    442  1.1  joerg   + ``-Wthread-safety-precise``: Requires that mutex expressions match precisely.
    443  1.1  joerg        This warning can be disabled for code which has a lot of aliases.
    444  1.1  joerg   + ``-Wthread-safety-reference``: Checks when guarded members are passed by reference.
    445  1.1  joerg 
    446  1.1  joerg 
    447  1.1  joerg :ref:`negative` are an experimental feature, which are enabled with:
    448  1.1  joerg 
    449  1.1  joerg * ``-Wthread-safety-negative``:  Negative capabilities.  Off by default.
    450  1.1  joerg 
    451  1.1  joerg When new features and checks are added to the analysis, they can often introduce
    452  1.1  joerg additional warnings.  Those warnings are initially released as *beta* warnings
    453  1.1  joerg for a period of time, after which they are migrated into the standard analysis.
    454  1.1  joerg 
    455  1.1  joerg * ``-Wthread-safety-beta``:  New features.  Off by default.
    456  1.1  joerg 
    457  1.1  joerg 
    458  1.1  joerg .. _negative:
    459  1.1  joerg 
    460  1.1  joerg Negative Capabilities
    461  1.1  joerg =====================
    462  1.1  joerg 
    463  1.1  joerg Thread Safety Analysis is designed to prevent both race conditions and
    464  1.1  joerg deadlock.  The GUARDED_BY and REQUIRES attributes prevent race conditions, by
    465  1.1  joerg ensuring that a capability is held before reading or writing to guarded data,
    466  1.1  joerg and the EXCLUDES attribute prevents deadlock, by making sure that a mutex is
    467  1.1  joerg *not* held.
    468  1.1  joerg 
    469  1.1  joerg However, EXCLUDES is an optional attribute, and does not provide the same
    470  1.1  joerg safety guarantee as REQUIRES.  In particular:
    471  1.1  joerg 
    472  1.1  joerg   * A function which acquires a capability does not have to exclude it.
    473  1.1  joerg   * A function which calls a function that excludes a capability does not
    474  1.1  joerg     have transitively exclude that capability.
    475  1.1  joerg 
    476  1.1  joerg As a result, EXCLUDES can easily produce false negatives:
    477  1.1  joerg 
    478  1.1  joerg .. code-block:: c++
    479  1.1  joerg 
    480  1.1  joerg   class Foo {
    481  1.1  joerg     Mutex mu;
    482  1.1  joerg 
    483  1.1  joerg     void foo() {
    484  1.1  joerg       mu.Lock();
    485  1.1  joerg       bar();           // No warning.
    486  1.1  joerg       baz();           // No warning.
    487  1.1  joerg       mu.Unlock();
    488  1.1  joerg     }
    489  1.1  joerg 
    490  1.1  joerg     void bar() {       // No warning.  (Should have EXCLUDES(mu)).
    491  1.1  joerg       mu.Lock();
    492  1.1  joerg       // ...
    493  1.1  joerg       mu.Unlock();
    494  1.1  joerg     }
    495  1.1  joerg 
    496  1.1  joerg     void baz() {
    497  1.1  joerg       bif();           // No warning.  (Should have EXCLUDES(mu)).
    498  1.1  joerg     }
    499  1.1  joerg 
    500  1.1  joerg     void bif() EXCLUDES(mu);
    501  1.1  joerg   };
    502  1.1  joerg 
    503  1.1  joerg 
    504  1.1  joerg Negative requirements are an alternative EXCLUDES that provide
    505  1.1  joerg a stronger safety guarantee.  A negative requirement uses the  REQUIRES
    506  1.1  joerg attribute, in conjunction with the ``!`` operator, to indicate that a capability
    507  1.1  joerg should *not* be held.
    508  1.1  joerg 
    509  1.1  joerg For example, using ``REQUIRES(!mu)`` instead of ``EXCLUDES(mu)`` will produce
    510  1.1  joerg the appropriate warnings:
    511  1.1  joerg 
    512  1.1  joerg .. code-block:: c++
    513  1.1  joerg 
    514  1.1  joerg   class FooNeg {
    515  1.1  joerg     Mutex mu;
    516  1.1  joerg 
    517  1.1  joerg     void foo() REQUIRES(!mu) {   // foo() now requires !mu.
    518  1.1  joerg       mu.Lock();
    519  1.1  joerg       bar();
    520  1.1  joerg       baz();
    521  1.1  joerg       mu.Unlock();
    522  1.1  joerg     }
    523  1.1  joerg 
    524  1.1  joerg     void bar() {
    525  1.1  joerg       mu.Lock();       // WARNING!  Missing REQUIRES(!mu).
    526  1.1  joerg       // ...
    527  1.1  joerg       mu.Unlock();
    528  1.1  joerg     }
    529  1.1  joerg 
    530  1.1  joerg     void baz() {
    531  1.1  joerg       bif();           // WARNING!  Missing REQUIRES(!mu).
    532  1.1  joerg     }
    533  1.1  joerg 
    534  1.1  joerg     void bif() REQUIRES(!mu);
    535  1.1  joerg   };
    536  1.1  joerg 
    537  1.1  joerg 
    538  1.1  joerg Negative requirements are an experimental feature which is off by default,
    539  1.1  joerg because it will produce many warnings in existing code.  It can be enabled
    540  1.1  joerg by passing ``-Wthread-safety-negative``.
    541  1.1  joerg 
    542  1.1  joerg 
    543  1.1  joerg .. _faq:
    544  1.1  joerg 
    545  1.1  joerg Frequently Asked Questions
    546  1.1  joerg ==========================
    547  1.1  joerg 
    548  1.1  joerg (Q) Should I put attributes in the header file, or in the .cc/.cpp/.cxx file?
    549  1.1  joerg 
    550  1.1  joerg (A) Attributes are part of the formal interface of a function, and should
    551  1.1  joerg always go in the header, where they are visible to anything that includes
    552  1.1  joerg the header.  Attributes in the .cpp file are not visible outside of the
    553  1.1  joerg immediate translation unit, which leads to false negatives and false positives.
    554  1.1  joerg 
    555  1.1  joerg 
    556  1.1  joerg (Q) "*Mutex is not locked on every path through here?*"  What does that mean?
    557  1.1  joerg 
    558  1.1  joerg (A) See :ref:`conditional_locks`, below.
    559  1.1  joerg 
    560  1.1  joerg 
    561  1.1  joerg .. _limitations:
    562  1.1  joerg 
    563  1.1  joerg Known Limitations
    564  1.1  joerg =================
    565  1.1  joerg 
    566  1.1  joerg Lexical scope
    567  1.1  joerg -------------
    568  1.1  joerg 
    569  1.1  joerg Thread safety attributes contain ordinary C++ expressions, and thus follow
    570  1.1  joerg ordinary C++ scoping rules.  In particular, this means that mutexes and other
    571  1.1  joerg capabilities must be declared before they can be used in an attribute.
    572  1.1  joerg Use-before-declaration is okay within a single class, because attributes are
    573  1.1  joerg parsed at the same time as method bodies. (C++ delays parsing of method bodies
    574  1.1  joerg until the end of the class.)  However, use-before-declaration is not allowed
    575  1.1  joerg between classes, as illustrated below.
    576  1.1  joerg 
    577  1.1  joerg .. code-block:: c++
    578  1.1  joerg 
    579  1.1  joerg   class Foo;
    580  1.1  joerg 
    581  1.1  joerg   class Bar {
    582  1.1  joerg     void bar(Foo* f) REQUIRES(f->mu);  // Error: mu undeclared.
    583  1.1  joerg   };
    584  1.1  joerg 
    585  1.1  joerg   class Foo {
    586  1.1  joerg     Mutex mu;
    587  1.1  joerg   };
    588  1.1  joerg 
    589  1.1  joerg 
    590  1.1  joerg Private Mutexes
    591  1.1  joerg ---------------
    592  1.1  joerg 
    593  1.1  joerg Good software engineering practice dictates that mutexes should be private
    594  1.1  joerg members, because the locking mechanism used by a thread-safe class is part of
    595  1.1  joerg its internal implementation.  However, private mutexes can sometimes leak into
    596  1.1  joerg the public interface of a class.
    597  1.1  joerg Thread safety attributes follow normal C++ access restrictions, so if ``mu``
    598  1.1  joerg is a private member of ``c``, then it is an error to write ``c.mu`` in an
    599  1.1  joerg attribute.
    600  1.1  joerg 
    601  1.1  joerg One workaround is to (ab)use the ``RETURN_CAPABILITY`` attribute to provide a
    602  1.1  joerg public *name* for a private mutex, without actually exposing the underlying
    603  1.1  joerg mutex.  For example:
    604  1.1  joerg 
    605  1.1  joerg .. code-block:: c++
    606  1.1  joerg 
    607  1.1  joerg   class MyClass {
    608  1.1  joerg   private:
    609  1.1  joerg     Mutex mu;
    610  1.1  joerg 
    611  1.1  joerg   public:
    612  1.1  joerg     // For thread safety analysis only.  Does not actually return mu.
    613  1.1  joerg     Mutex* getMu() RETURN_CAPABILITY(mu) { return 0; }
    614  1.1  joerg 
    615  1.1  joerg     void doSomething() REQUIRES(mu);
    616  1.1  joerg   };
    617  1.1  joerg 
    618  1.1  joerg   void doSomethingTwice(MyClass& c) REQUIRES(c.getMu()) {
    619  1.1  joerg     // The analysis thinks that c.getMu() == c.mu
    620  1.1  joerg     c.doSomething();
    621  1.1  joerg     c.doSomething();
    622  1.1  joerg   }
    623  1.1  joerg 
    624  1.1  joerg In the above example, ``doSomethingTwice()`` is an external routine that
    625  1.1  joerg requires ``c.mu`` to be locked, which cannot be declared directly because ``mu``
    626  1.1  joerg is private.  This pattern is discouraged because it
    627  1.1  joerg violates encapsulation, but it is sometimes necessary, especially when adding
    628  1.1  joerg annotations to an existing code base.  The workaround is to define ``getMu()``
    629  1.1  joerg as a fake getter method, which is provided only for the benefit of thread
    630  1.1  joerg safety analysis.
    631  1.1  joerg 
    632  1.1  joerg 
    633  1.1  joerg .. _conditional_locks:
    634  1.1  joerg 
    635  1.1  joerg No conditionally held locks.
    636  1.1  joerg ----------------------------
    637  1.1  joerg 
    638  1.1  joerg The analysis must be able to determine whether a lock is held, or not held, at
    639  1.1  joerg every program point.  Thus, sections of code where a lock *might be held* will
    640  1.1  joerg generate spurious warnings (false positives).  For example:
    641  1.1  joerg 
    642  1.1  joerg .. code-block:: c++
    643  1.1  joerg 
    644  1.1  joerg   void foo() {
    645  1.1  joerg     bool b = needsToLock();
    646  1.1  joerg     if (b) mu.Lock();
    647  1.1  joerg     ...  // Warning!  Mutex 'mu' is not held on every path through here.
    648  1.1  joerg     if (b) mu.Unlock();
    649  1.1  joerg   }
    650  1.1  joerg 
    651  1.1  joerg 
    652  1.1  joerg No checking inside constructors and destructors.
    653  1.1  joerg ------------------------------------------------
    654  1.1  joerg 
    655  1.1  joerg The analysis currently does not do any checking inside constructors or
    656  1.1  joerg destructors.  In other words, every constructor and destructor is treated as
    657  1.1  joerg if it was annotated with ``NO_THREAD_SAFETY_ANALYSIS``.
    658  1.1  joerg The reason for this is that during initialization, only one thread typically
    659  1.1  joerg has access to the object which is being initialized, and it is thus safe (and
    660  1.1  joerg common practice) to initialize guarded members without acquiring any locks.
    661  1.1  joerg The same is true of destructors.
    662  1.1  joerg 
    663  1.1  joerg Ideally, the analysis would allow initialization of guarded members inside the
    664  1.1  joerg object being initialized or destroyed, while still enforcing the usual access
    665  1.1  joerg restrictions on everything else.  However, this is difficult to enforce in
    666  1.1  joerg practice, because in complex pointer-based data structures, it is hard to
    667  1.1  joerg determine what data is owned by the enclosing object.
    668  1.1  joerg 
    669  1.1  joerg No inlining.
    670  1.1  joerg ------------
    671  1.1  joerg 
    672  1.1  joerg Thread safety analysis is strictly intra-procedural, just like ordinary type
    673  1.1  joerg checking.  It relies only on the declared attributes of a function, and will
    674  1.1  joerg not attempt to inline any method calls.  As a result, code such as the
    675  1.1  joerg following will not work:
    676  1.1  joerg 
    677  1.1  joerg .. code-block:: c++
    678  1.1  joerg 
    679  1.1  joerg   template<class T>
    680  1.1  joerg   class AutoCleanup {
    681  1.1  joerg     T* object;
    682  1.1  joerg     void (T::*mp)();
    683  1.1  joerg 
    684  1.1  joerg   public:
    685  1.1  joerg     AutoCleanup(T* obj, void (T::*imp)()) : object(obj), mp(imp) { }
    686  1.1  joerg     ~AutoCleanup() { (object->*mp)(); }
    687  1.1  joerg   };
    688  1.1  joerg 
    689  1.1  joerg   Mutex mu;
    690  1.1  joerg   void foo() {
    691  1.1  joerg     mu.Lock();
    692  1.1  joerg     AutoCleanup<Mutex>(&mu, &Mutex::Unlock);
    693  1.1  joerg     // ...
    694  1.1  joerg   }  // Warning, mu is not unlocked.
    695  1.1  joerg 
    696  1.1  joerg In this case, the destructor of ``Autocleanup`` calls ``mu.Unlock()``, so
    697  1.1  joerg the warning is bogus.  However,
    698  1.1  joerg thread safety analysis cannot see the unlock, because it does not attempt to
    699  1.1  joerg inline the destructor.  Moreover, there is no way to annotate the destructor,
    700  1.1  joerg because the destructor is calling a function that is not statically known.
    701  1.1  joerg This pattern is simply not supported.
    702  1.1  joerg 
    703  1.1  joerg 
    704  1.1  joerg No alias analysis.
    705  1.1  joerg ------------------
    706  1.1  joerg 
    707  1.1  joerg The analysis currently does not track pointer aliases.  Thus, there can be
    708  1.1  joerg false positives if two pointers both point to the same mutex.
    709  1.1  joerg 
    710  1.1  joerg 
    711  1.1  joerg .. code-block:: c++
    712  1.1  joerg 
    713  1.1  joerg   class MutexUnlocker {
    714  1.1  joerg     Mutex* mu;
    715  1.1  joerg 
    716  1.1  joerg   public:
    717  1.1  joerg     MutexUnlocker(Mutex* m) RELEASE(m) : mu(m)  { mu->Unlock(); }
    718  1.1  joerg     ~MutexUnlocker() ACQUIRE(mu) { mu->Lock(); }
    719  1.1  joerg   };
    720  1.1  joerg 
    721  1.1  joerg   Mutex mutex;
    722  1.1  joerg   void test() REQUIRES(mutex) {
    723  1.1  joerg     {
    724  1.1  joerg       MutexUnlocker munl(&mutex);  // unlocks mutex
    725  1.1  joerg       doSomeIO();
    726  1.1  joerg     }                              // Warning: locks munl.mu
    727  1.1  joerg   }
    728  1.1  joerg 
    729  1.1  joerg The MutexUnlocker class is intended to be the dual of the MutexLocker class,
    730  1.1  joerg defined in :ref:`mutexheader`.  However, it doesn't work because the analysis
    731  1.1  joerg doesn't know that munl.mu == mutex.  The SCOPED_CAPABILITY attribute handles
    732  1.1  joerg aliasing for MutexLocker, but does so only for that particular pattern.
    733  1.1  joerg 
    734  1.1  joerg 
    735  1.1  joerg ACQUIRED_BEFORE(...) and ACQUIRED_AFTER(...) are currently unimplemented.
    736  1.1  joerg -------------------------------------------------------------------------
    737  1.1  joerg 
    738  1.1  joerg To be fixed in a future update.
    739  1.1  joerg 
    740  1.1  joerg 
    741  1.1  joerg .. _mutexheader:
    742  1.1  joerg 
    743  1.1  joerg mutex.h
    744  1.1  joerg =======
    745  1.1  joerg 
    746  1.1  joerg Thread safety analysis can be used with any threading library, but it does
    747  1.1  joerg require that the threading API be wrapped in classes and methods which have the
    748  1.1  joerg appropriate annotations.  The following code provides ``mutex.h`` as an example;
    749  1.1  joerg these methods should be filled in to call the appropriate underlying
    750  1.1  joerg implementation.
    751  1.1  joerg 
    752  1.1  joerg 
    753  1.1  joerg .. code-block:: c++
    754  1.1  joerg 
    755  1.1  joerg 
    756  1.1  joerg   #ifndef THREAD_SAFETY_ANALYSIS_MUTEX_H
    757  1.1  joerg   #define THREAD_SAFETY_ANALYSIS_MUTEX_H
    758  1.1  joerg 
    759  1.1  joerg   // Enable thread safety attributes only with clang.
    760  1.1  joerg   // The attributes can be safely erased when compiling with other compilers.
    761  1.1  joerg   #if defined(__clang__) && (!defined(SWIG))
    762  1.1  joerg   #define THREAD_ANNOTATION_ATTRIBUTE__(x)   __attribute__((x))
    763  1.1  joerg   #else
    764  1.1  joerg   #define THREAD_ANNOTATION_ATTRIBUTE__(x)   // no-op
    765  1.1  joerg   #endif
    766  1.1  joerg 
    767  1.1  joerg   #define CAPABILITY(x) \
    768  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(capability(x))
    769  1.1  joerg 
    770  1.1  joerg   #define SCOPED_CAPABILITY \
    771  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
    772  1.1  joerg 
    773  1.1  joerg   #define GUARDED_BY(x) \
    774  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x))
    775  1.1  joerg 
    776  1.1  joerg   #define PT_GUARDED_BY(x) \
    777  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x))
    778  1.1  joerg 
    779  1.1  joerg   #define ACQUIRED_BEFORE(...) \
    780  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__))
    781  1.1  joerg 
    782  1.1  joerg   #define ACQUIRED_AFTER(...) \
    783  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__))
    784  1.1  joerg 
    785  1.1  joerg   #define REQUIRES(...) \
    786  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__))
    787  1.1  joerg 
    788  1.1  joerg   #define REQUIRES_SHARED(...) \
    789  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__))
    790  1.1  joerg 
    791  1.1  joerg   #define ACQUIRE(...) \
    792  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__))
    793  1.1  joerg 
    794  1.1  joerg   #define ACQUIRE_SHARED(...) \
    795  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__))
    796  1.1  joerg 
    797  1.1  joerg   #define RELEASE(...) \
    798  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__))
    799  1.1  joerg 
    800  1.1  joerg   #define RELEASE_SHARED(...) \
    801  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__))
    802  1.1  joerg 
    803  1.1  joerg   #define TRY_ACQUIRE(...) \
    804  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__))
    805  1.1  joerg 
    806  1.1  joerg   #define TRY_ACQUIRE_SHARED(...) \
    807  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__))
    808  1.1  joerg 
    809  1.1  joerg   #define EXCLUDES(...) \
    810  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
    811  1.1  joerg 
    812  1.1  joerg   #define ASSERT_CAPABILITY(x) \
    813  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x))
    814  1.1  joerg 
    815  1.1  joerg   #define ASSERT_SHARED_CAPABILITY(x) \
    816  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x))
    817  1.1  joerg 
    818  1.1  joerg   #define RETURN_CAPABILITY(x) \
    819  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
    820  1.1  joerg 
    821  1.1  joerg   #define NO_THREAD_SAFETY_ANALYSIS \
    822  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis)
    823  1.1  joerg 
    824  1.1  joerg 
    825  1.1  joerg   // Defines an annotated interface for mutexes.
    826  1.1  joerg   // These methods can be implemented to use any internal mutex implementation.
    827  1.1  joerg   class CAPABILITY("mutex") Mutex {
    828  1.1  joerg   public:
    829  1.1  joerg     // Acquire/lock this mutex exclusively.  Only one thread can have exclusive
    830  1.1  joerg     // access at any one time.  Write operations to guarded data require an
    831  1.1  joerg     // exclusive lock.
    832  1.1  joerg     void Lock() ACQUIRE();
    833  1.1  joerg 
    834  1.1  joerg     // Acquire/lock this mutex for read operations, which require only a shared
    835  1.1  joerg     // lock.  This assumes a multiple-reader, single writer semantics.  Multiple
    836  1.1  joerg     // threads may acquire the mutex simultaneously as readers, but a writer
    837  1.1  joerg     // must wait for all of them to release the mutex before it can acquire it
    838  1.1  joerg     // exclusively.
    839  1.1  joerg     void ReaderLock() ACQUIRE_SHARED();
    840  1.1  joerg 
    841  1.1  joerg     // Release/unlock an exclusive mutex.
    842  1.1  joerg     void Unlock() RELEASE();
    843  1.1  joerg 
    844  1.1  joerg     // Release/unlock a shared mutex.
    845  1.1  joerg     void ReaderUnlock() RELEASE_SHARED();
    846  1.1  joerg 
    847  1.1  joerg     // Try to acquire the mutex.  Returns true on success, and false on failure.
    848  1.1  joerg     bool TryLock() TRY_ACQUIRE(true);
    849  1.1  joerg 
    850  1.1  joerg     // Try to acquire the mutex for read operations.
    851  1.1  joerg     bool ReaderTryLock() TRY_ACQUIRE_SHARED(true);
    852  1.1  joerg 
    853  1.1  joerg     // Assert that this mutex is currently held by the calling thread.
    854  1.1  joerg     void AssertHeld() ASSERT_CAPABILITY(this);
    855  1.1  joerg 
    856  1.1  joerg     // Assert that is mutex is currently held for read operations.
    857  1.1  joerg     void AssertReaderHeld() ASSERT_SHARED_CAPABILITY(this);
    858  1.1  joerg     
    859  1.1  joerg     // For negative capabilities.
    860  1.1  joerg     const Mutex& operator!() const { return *this; }
    861  1.1  joerg   };
    862  1.1  joerg 
    863  1.1  joerg 
    864  1.1  joerg   // MutexLocker is an RAII class that acquires a mutex in its constructor, and
    865  1.1  joerg   // releases it in its destructor.
    866  1.1  joerg   class SCOPED_CAPABILITY MutexLocker {
    867  1.1  joerg   private:
    868  1.1  joerg     Mutex* mut;
    869  1.1  joerg 
    870  1.1  joerg   public:
    871  1.1  joerg     MutexLocker(Mutex *mu) ACQUIRE(mu) : mut(mu) {
    872  1.1  joerg       mu->Lock();
    873  1.1  joerg     }
    874  1.1  joerg     ~MutexLocker() RELEASE() {
    875  1.1  joerg       mut->Unlock();
    876  1.1  joerg     }
    877  1.1  joerg   };
    878  1.1  joerg 
    879  1.1  joerg 
    880  1.1  joerg   #ifdef USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
    881  1.1  joerg   // The original version of thread safety analysis the following attribute
    882  1.1  joerg   // definitions.  These use a lock-based terminology.  They are still in use
    883  1.1  joerg   // by existing thread safety code, and will continue to be supported.
    884  1.1  joerg 
    885  1.1  joerg   // Deprecated.
    886  1.1  joerg   #define PT_GUARDED_VAR \
    887  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_var)
    888  1.1  joerg 
    889  1.1  joerg   // Deprecated.
    890  1.1  joerg   #define GUARDED_VAR \
    891  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(guarded_var)
    892  1.1  joerg 
    893  1.1  joerg   // Replaced by REQUIRES
    894  1.1  joerg   #define EXCLUSIVE_LOCKS_REQUIRED(...) \
    895  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(exclusive_locks_required(__VA_ARGS__))
    896  1.1  joerg 
    897  1.1  joerg   // Replaced by REQUIRES_SHARED
    898  1.1  joerg   #define SHARED_LOCKS_REQUIRED(...) \
    899  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(shared_locks_required(__VA_ARGS__))
    900  1.1  joerg 
    901  1.1  joerg   // Replaced by CAPABILITY
    902  1.1  joerg   #define LOCKABLE \
    903  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(lockable)
    904  1.1  joerg 
    905  1.1  joerg   // Replaced by SCOPED_CAPABILITY
    906  1.1  joerg   #define SCOPED_LOCKABLE \
    907  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable)
    908  1.1  joerg 
    909  1.1  joerg   // Replaced by ACQUIRE
    910  1.1  joerg   #define EXCLUSIVE_LOCK_FUNCTION(...) \
    911  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(exclusive_lock_function(__VA_ARGS__))
    912  1.1  joerg 
    913  1.1  joerg   // Replaced by ACQUIRE_SHARED
    914  1.1  joerg   #define SHARED_LOCK_FUNCTION(...) \
    915  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(shared_lock_function(__VA_ARGS__))
    916  1.1  joerg 
    917  1.1  joerg   // Replaced by RELEASE and RELEASE_SHARED
    918  1.1  joerg   #define UNLOCK_FUNCTION(...) \
    919  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(unlock_function(__VA_ARGS__))
    920  1.1  joerg 
    921  1.1  joerg   // Replaced by TRY_ACQUIRE
    922  1.1  joerg   #define EXCLUSIVE_TRYLOCK_FUNCTION(...) \
    923  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(exclusive_trylock_function(__VA_ARGS__))
    924  1.1  joerg 
    925  1.1  joerg   // Replaced by TRY_ACQUIRE_SHARED
    926  1.1  joerg   #define SHARED_TRYLOCK_FUNCTION(...) \
    927  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(shared_trylock_function(__VA_ARGS__))
    928  1.1  joerg 
    929  1.1  joerg   // Replaced by ASSERT_CAPABILITY
    930  1.1  joerg   #define ASSERT_EXCLUSIVE_LOCK(...) \
    931  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(assert_exclusive_lock(__VA_ARGS__))
    932  1.1  joerg 
    933  1.1  joerg   // Replaced by ASSERT_SHARED_CAPABILITY
    934  1.1  joerg   #define ASSERT_SHARED_LOCK(...) \
    935  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_lock(__VA_ARGS__))
    936  1.1  joerg 
    937  1.1  joerg   // Replaced by EXCLUDE_CAPABILITY.
    938  1.1  joerg   #define LOCKS_EXCLUDED(...) \
    939  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__))
    940  1.1  joerg 
    941  1.1  joerg   // Replaced by RETURN_CAPABILITY
    942  1.1  joerg   #define LOCK_RETURNED(x) \
    943  1.1  joerg     THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x))
    944  1.1  joerg 
    945  1.1  joerg   #endif  // USE_LOCK_STYLE_THREAD_SAFETY_ATTRIBUTES
    946  1.1  joerg 
    947  1.1  joerg   #endif  // THREAD_SAFETY_ANALYSIS_MUTEX_H
    948  1.1  joerg 
    949