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 | |||||
Hal Canary | 22be4c4 | 2018-06-12 12:37:31 -0400 | [diff] [blame] | 11 | #include "../private/SkMacros.h" |
herb | 7f0a3d7 | 2015-09-24 07:34:49 -0700 | [diff] [blame] | 12 | #include "../private/SkSemaphore.h" |
mtklein | 42846ed | 2016-05-05 10:57:37 -0700 | [diff] [blame] | 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 |