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 "../private/SkMacros.h" 12 #include "../private/SkSemaphore.h" 13 #include "../private/SkThreadID.h" 14 #include "SkTypes.h" 15 16 #define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name; 17 18 class SkBaseMutex { 19 public: 20 constexpr SkBaseMutex() = default; 21 acquire()22 void acquire() { 23 fSemaphore.wait(); 24 SkDEBUGCODE(fOwner = SkGetThreadID();) 25 } 26 release()27 void release() { 28 this->assertHeld(); 29 SkDEBUGCODE(fOwner = kIllegalThreadID;) 30 fSemaphore.signal(); 31 } 32 assertHeld()33 void assertHeld() { 34 SkASSERT(fOwner == SkGetThreadID()); 35 } 36 37 protected: 38 SkBaseSemaphore fSemaphore{1}; 39 SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};) 40 }; 41 42 class SkMutex : public SkBaseMutex { 43 public: 44 using SkBaseMutex::SkBaseMutex; ~SkMutex()45 ~SkMutex() { fSemaphore.cleanup(); } 46 }; 47 48 class SkAutoMutexAcquire { 49 public: 50 template <typename T> SkAutoMutexAcquire(T * mutex)51 SkAutoMutexAcquire(T* mutex) : fMutex(mutex) { 52 if (mutex) { 53 mutex->acquire(); 54 } 55 fRelease = [](void* mutex) { ((T*)mutex)->release(); }; 56 } 57 58 template <typename T> SkAutoMutexAcquire(T & mutex)59 SkAutoMutexAcquire(T& mutex) : SkAutoMutexAcquire(&mutex) {} 60 ~SkAutoMutexAcquire()61 ~SkAutoMutexAcquire() { this->release(); } 62 release()63 void release() { 64 if (fMutex) { 65 fRelease(fMutex); 66 } 67 fMutex = nullptr; 68 } 69 70 private: 71 void* fMutex; 72 void (*fRelease)(void*); 73 }; 74 #define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire) 75 76 // SkAutoExclusive is a lighter weight version of SkAutoMutexAcquire. 77 // It assumes that there is a valid mutex, obviating the null check. 78 class SkAutoExclusive { 79 public: 80 template <typename T> SkAutoExclusive(T & mutex)81 SkAutoExclusive(T& mutex) : fMutex(&mutex) { 82 mutex.acquire(); 83 84 fRelease = [](void* mutex) { ((T*)mutex)->release(); }; 85 } ~SkAutoExclusive()86 ~SkAutoExclusive() { fRelease(fMutex); } 87 88 private: 89 void* fMutex; 90 void (*fRelease)(void*); 91 }; 92 #define SkAutoExclusive(...) SK_REQUIRE_LOCAL_VAR(SkAutoExclusive) 93 94 #endif//SkMutex_DEFINED 95