1 /* 2 * Copyright 2015 Google Inc. 3 * 4 * Use of this source code is governed by a BSD-style license that can be 5 * found in the LICENSE file. 6 */ 7 8 #ifndef SkMutex_DEFINED 9 #define SkMutex_DEFINED 10 11 #include "include/private/base/SkAssert.h" 12 #include "include/private/base/SkDebug.h" 13 #include "include/private/base/SkSemaphore.h" 14 #include "include/private/base/SkThreadAnnotations.h" 15 #include "include/private/base/SkThreadID.h" 16 17 class SK_CAPABILITY("mutex") SkMutex { 18 public: 19 constexpr SkMutex() = default; 20 ~SkMutex()21 ~SkMutex() { 22 this->assertNotHeld(); 23 } 24 acquire()25 void acquire() SK_ACQUIRE() { 26 fSemaphore.wait(); 27 SkDEBUGCODE(fOwner = SkGetThreadID();) 28 } 29 release()30 void release() SK_RELEASE_CAPABILITY() { 31 this->assertHeld(); 32 SkDEBUGCODE(fOwner = kIllegalThreadID;) 33 fSemaphore.signal(); 34 } 35 assertHeld()36 void assertHeld() SK_ASSERT_CAPABILITY(this) { 37 SkASSERT(fOwner == SkGetThreadID()); 38 } 39 assertNotHeld()40 void assertNotHeld() { 41 SkASSERT(fOwner == kIllegalThreadID); 42 } 43 44 private: 45 SkSemaphore fSemaphore{1}; 46 SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};) 47 }; 48 49 class SK_SCOPED_CAPABILITY SkAutoMutexExclusive { 50 public: SkAutoMutexExclusive(SkMutex & mutex)51 SkAutoMutexExclusive(SkMutex& mutex) SK_ACQUIRE(mutex) : fMutex(mutex) { fMutex.acquire(); } SK_RELEASE_CAPABILITY()52 ~SkAutoMutexExclusive() SK_RELEASE_CAPABILITY() { fMutex.release(); } 53 54 SkAutoMutexExclusive(const SkAutoMutexExclusive&) = delete; 55 SkAutoMutexExclusive(SkAutoMutexExclusive&&) = delete; 56 57 SkAutoMutexExclusive& operator=(const SkAutoMutexExclusive&) = delete; 58 SkAutoMutexExclusive& operator=(SkAutoMutexExclusive&&) = delete; 59 60 private: 61 SkMutex& fMutex; 62 }; 63 64 #endif // SkMutex_DEFINED 65