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