1 // Based on https://clang.llvm.org/docs/ThreadSafetyAnalysis.html 2 #ifndef SIMPLE_WEB_MUTEX_HPP 3 #define SIMPLE_WEB_MUTEX_HPP 4 5 #include <mutex> 6 7 // Enable thread safety attributes only with clang. 8 #if defined(__clang__) && (!defined(SWIG)) 9 #define THREAD_ANNOTATION_ATTRIBUTE__(x) __attribute__((x)) 10 #else 11 #define THREAD_ANNOTATION_ATTRIBUTE__(x) // no-op 12 #endif 13 14 #define CAPABILITY(x) \ 15 THREAD_ANNOTATION_ATTRIBUTE__(capability(x)) 16 17 #define SCOPED_CAPABILITY \ 18 THREAD_ANNOTATION_ATTRIBUTE__(scoped_lockable) 19 20 #define GUARDED_BY(x) \ 21 THREAD_ANNOTATION_ATTRIBUTE__(guarded_by(x)) 22 23 #define PT_GUARDED_BY(x) \ 24 THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_by(x)) 25 26 #define ACQUIRED_BEFORE(...) \ 27 THREAD_ANNOTATION_ATTRIBUTE__(acquired_before(__VA_ARGS__)) 28 29 #define ACQUIRED_AFTER(...) \ 30 THREAD_ANNOTATION_ATTRIBUTE__(acquired_after(__VA_ARGS__)) 31 32 #define REQUIRES(...) \ 33 THREAD_ANNOTATION_ATTRIBUTE__(requires_capability(__VA_ARGS__)) 34 35 #define REQUIRES_SHARED(...) \ 36 THREAD_ANNOTATION_ATTRIBUTE__(requires_shared_capability(__VA_ARGS__)) 37 38 #define ACQUIRE(...) \ 39 THREAD_ANNOTATION_ATTRIBUTE__(acquire_capability(__VA_ARGS__)) 40 41 #define ACQUIRE_SHARED(...) \ 42 THREAD_ANNOTATION_ATTRIBUTE__(acquire_shared_capability(__VA_ARGS__)) 43 44 #define RELEASE(...) \ 45 THREAD_ANNOTATION_ATTRIBUTE__(release_capability(__VA_ARGS__)) 46 47 #define RELEASE_SHARED(...) \ 48 THREAD_ANNOTATION_ATTRIBUTE__(release_shared_capability(__VA_ARGS__)) 49 50 #define TRY_ACQUIRE(...) \ 51 THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_capability(__VA_ARGS__)) 52 53 #define TRY_ACQUIRE_SHARED(...) \ 54 THREAD_ANNOTATION_ATTRIBUTE__(try_acquire_shared_capability(__VA_ARGS__)) 55 56 #define EXCLUDES(...) \ 57 THREAD_ANNOTATION_ATTRIBUTE__(locks_excluded(__VA_ARGS__)) 58 59 #define ASSERT_CAPABILITY(x) \ 60 THREAD_ANNOTATION_ATTRIBUTE__(assert_capability(x)) 61 62 #define ASSERT_SHARED_CAPABILITY(x) \ 63 THREAD_ANNOTATION_ATTRIBUTE__(assert_shared_capability(x)) 64 65 #define RETURN_CAPABILITY(x) \ 66 THREAD_ANNOTATION_ATTRIBUTE__(lock_returned(x)) 67 68 #define NO_THREAD_SAFETY_ANALYSIS \ 69 THREAD_ANNOTATION_ATTRIBUTE__(no_thread_safety_analysis) 70 71 namespace SimpleWeb { 72 /// Mutex class that is annotated for Clang Thread Safety Analysis. 73 class CAPABILITY("mutex") Mutex { 74 std::mutex mutex; 75 76 public: lock()77 void lock() ACQUIRE() { 78 mutex.lock(); 79 } 80 unlock()81 void unlock() RELEASE() { 82 mutex.unlock(); 83 } 84 }; 85 86 /// Scoped mutex guard class that is annotated for Clang Thread Safety Analysis. 87 class SCOPED_CAPABILITY LockGuard { 88 Mutex &mutex; 89 bool locked = true; 90 91 public: ACQUIRE(mutex_)92 LockGuard(Mutex &mutex_) ACQUIRE(mutex_) : mutex(mutex_) { 93 mutex.lock(); 94 } unlock()95 void unlock() RELEASE() { 96 mutex.unlock(); 97 locked = false; 98 } RELEASE()99 ~LockGuard() RELEASE() { 100 if(locked) 101 mutex.unlock(); 102 } 103 }; 104 105 } // namespace SimpleWeb 106 107 #endif // SIMPLE_WEB_MUTEX_HPP 108