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