herb | ac09471 | 2015-07-09 13:44:32 -0700 | [diff] [blame] | 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 | |
mtklein | a64c48f | 2015-01-21 13:13:31 -0800 | [diff] [blame] | 8 | #ifndef SkMutex_DEFINED |
| 9 | #define SkMutex_DEFINED |
| 10 | |
Mike Klein | d9187c0 | 2018-09-07 17:32:47 +0000 | [diff] [blame] | 11 | #include "../private/SkMacros.h" |
| 12 | #include "../private/SkSemaphore.h" |
| 13 | #include "../private/SkThreadID.h" |
mtklein | a64c48f | 2015-01-21 13:13:31 -0800 | [diff] [blame] | 14 | #include "SkTypes.h" |
| 15 | |
mtklein | 42846ed | 2016-05-05 10:57:37 -0700 | [diff] [blame] | 16 | #define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name; |
reed | 086eea9 | 2016-05-04 17:12:46 -0700 | [diff] [blame] | 17 | |
mtklein | 42846ed | 2016-05-05 10:57:37 -0700 | [diff] [blame] | 18 | class SkBaseMutex { |
| 19 | public: |
| 20 | constexpr SkBaseMutex() = default; |
herb | 7f0a3d7 | 2015-09-24 07:34:49 -0700 | [diff] [blame] | 21 | |
herb | 7f0a3d7 | 2015-09-24 07:34:49 -0700 | [diff] [blame] | 22 | void acquire() { |
| 23 | fSemaphore.wait(); |
herb | e4c1735 | 2015-09-29 14:38:01 -0700 | [diff] [blame] | 24 | SkDEBUGCODE(fOwner = SkGetThreadID();) |
herb | 7f0a3d7 | 2015-09-24 07:34:49 -0700 | [diff] [blame] | 25 | } |
| 26 | |
| 27 | void release() { |
| 28 | this->assertHeld(); |
herb | e4c1735 | 2015-09-29 14:38:01 -0700 | [diff] [blame] | 29 | SkDEBUGCODE(fOwner = kIllegalThreadID;) |
herb | 7f0a3d7 | 2015-09-24 07:34:49 -0700 | [diff] [blame] | 30 | fSemaphore.signal(); |
| 31 | } |
| 32 | |
| 33 | void assertHeld() { |
herb | e4c1735 | 2015-09-29 14:38:01 -0700 | [diff] [blame] | 34 | SkASSERT(fOwner == SkGetThreadID()); |
herb | 7f0a3d7 | 2015-09-24 07:34:49 -0700 | [diff] [blame] | 35 | } |
| 36 | |
mtklein | 42846ed | 2016-05-05 10:57:37 -0700 | [diff] [blame] | 37 | protected: |
| 38 | SkBaseSemaphore fSemaphore{1}; |
| 39 | SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};) |
sclittle | d9f5d20 | 2016-05-04 18:23:30 -0700 | [diff] [blame] | 40 | }; |
| 41 | |
sclittle | d9f5d20 | 2016-05-04 18:23:30 -0700 | [diff] [blame] | 42 | class SkMutex : public SkBaseMutex { |
| 43 | public: |
Mike Klein | 3b7658a | 2017-09-20 09:53:39 -0400 | [diff] [blame] | 44 | using SkBaseMutex::SkBaseMutex; |
| 45 | ~SkMutex() { fSemaphore.cleanup(); } |
herb | 7f0a3d7 | 2015-09-24 07:34:49 -0700 | [diff] [blame] | 46 | }; |
mtklein | a64c48f | 2015-01-21 13:13:31 -0800 | [diff] [blame] | 47 | |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 48 | class SkAutoMutexAcquire { |
mtklein | a669bc7 | 2015-02-02 12:22:07 -0800 | [diff] [blame] | 49 | public: |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 50 | template <typename T> |
| 51 | SkAutoMutexAcquire(T* mutex) : fMutex(mutex) { |
mtklein | a669bc7 | 2015-02-02 12:22:07 -0800 | [diff] [blame] | 52 | if (mutex) { |
| 53 | mutex->acquire(); |
| 54 | } |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 55 | fRelease = [](void* mutex) { ((T*)mutex)->release(); }; |
mtklein | a669bc7 | 2015-02-02 12:22:07 -0800 | [diff] [blame] | 56 | } |
| 57 | |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 58 | template <typename T> |
| 59 | SkAutoMutexAcquire(T& mutex) : SkAutoMutexAcquire(&mutex) {} |
mtklein | a669bc7 | 2015-02-02 12:22:07 -0800 | [diff] [blame] | 60 | |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 61 | ~SkAutoMutexAcquire() { this->release(); } |
| 62 | |
mtklein | a669bc7 | 2015-02-02 12:22:07 -0800 | [diff] [blame] | 63 | void release() { |
| 64 | if (fMutex) { |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 65 | fRelease(fMutex); |
mtklein | a669bc7 | 2015-02-02 12:22:07 -0800 | [diff] [blame] | 66 | } |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 67 | fMutex = nullptr; |
mtklein | a669bc7 | 2015-02-02 12:22:07 -0800 | [diff] [blame] | 68 | } |
| 69 | |
| 70 | private: |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 71 | void* fMutex; |
| 72 | void (*fRelease)(void*); |
mtklein | a669bc7 | 2015-02-02 12:22:07 -0800 | [diff] [blame] | 73 | }; |
| 74 | #define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire) |
| 75 | |
mtklein | f10637f | 2016-06-10 13:56:35 -0700 | [diff] [blame] | 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> |
| 81 | SkAutoExclusive(T& mutex) : fMutex(&mutex) { |
| 82 | mutex.acquire(); |
| 83 | |
| 84 | fRelease = [](void* mutex) { ((T*)mutex)->release(); }; |
| 85 | } |
| 86 | ~SkAutoExclusive() { fRelease(fMutex); } |
| 87 | |
| 88 | private: |
| 89 | void* fMutex; |
| 90 | void (*fRelease)(void*); |
| 91 | }; |
| 92 | #define SkAutoExclusive(...) SK_REQUIRE_LOCAL_VAR(SkAutoExclusive) |
herb | 12449a9 | 2015-10-21 19:11:13 -0700 | [diff] [blame] | 93 | |
mtklein | a64c48f | 2015-01-21 13:13:31 -0800 | [diff] [blame] | 94 | #endif//SkMutex_DEFINED |