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