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