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 /** 18 * class SkMutex 19 * 20 * This allows us to have a mutex without needing the one in 21 * the C++ std library which does not work with all clients. 22 * go/cstyle#Disallowed_Stdlib 23 */ 24 25 class SK_CAPABILITY("mutex") SkMutex { 26 public: 27 constexpr SkMutex() = default; 28 ~SkMutex()29 ~SkMutex() { 30 this->assertNotHeld(); 31 } 32 acquire()33 void acquire() SK_ACQUIRE() { 34 fSemaphore.wait(); 35 SkDEBUGCODE(fOwner = SkGetThreadID();) 36 } 37 release()38 void release() SK_RELEASE_CAPABILITY() { 39 this->assertHeld(); 40 SkDEBUGCODE(fOwner = kIllegalThreadID;) 41 fSemaphore.signal(); 42 } 43 assertHeld()44 void assertHeld() SK_ASSERT_CAPABILITY(this) { 45 SkASSERT(fOwner == SkGetThreadID()); 46 } 47 assertNotHeld()48 void assertNotHeld() { 49 SkASSERT(fOwner == kIllegalThreadID); 50 } 51 52 private: 53 SkSemaphore fSemaphore{1}; 54 SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};) 55 }; 56 57 class SK_SCOPED_CAPABILITY SkAutoMutexExclusive { 58 public: SkAutoMutexExclusive(SkMutex & mutex)59 SkAutoMutexExclusive(SkMutex& mutex) SK_ACQUIRE(mutex) : fMutex(mutex) { fMutex.acquire(); } SK_RELEASE_CAPABILITY()60 ~SkAutoMutexExclusive() SK_RELEASE_CAPABILITY() { fMutex.release(); } 61 62 SkAutoMutexExclusive(const SkAutoMutexExclusive&) = delete; 63 SkAutoMutexExclusive(SkAutoMutexExclusive&&) = delete; 64 65 SkAutoMutexExclusive& operator=(const SkAutoMutexExclusive&) = delete; 66 SkAutoMutexExclusive& operator=(SkAutoMutexExclusive&&) = delete; 67 68 private: 69 SkMutex& fMutex; 70 }; 71 72 #endif // SkMutex_DEFINED 73