blob: 9af23adadf0a10f43a98d61f3ae3fbbfb729d120 [file] [log] [blame]
herbac094712015-07-09 13:44:32 -07001/*
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
mtkleina64c48f2015-01-21 13:13:31 -08008#ifndef SkMutex_DEFINED
9#define SkMutex_DEFINED
10
Hal Canary22be4c42018-06-12 12:37:31 -040011#include "../private/SkMacros.h"
herb7f0a3d72015-09-24 07:34:49 -070012#include "../private/SkSemaphore.h"
mtklein42846ed2016-05-05 10:57:37 -070013#include "../private/SkThreadID.h"
mtkleina64c48f2015-01-21 13:13:31 -080014#include "SkTypes.h"
15
mtklein42846ed2016-05-05 10:57:37 -070016#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name;
reed086eea92016-05-04 17:12:46 -070017
mtklein42846ed2016-05-05 10:57:37 -070018class SkBaseMutex {
19public:
20 constexpr SkBaseMutex() = default;
herb7f0a3d72015-09-24 07:34:49 -070021
herb7f0a3d72015-09-24 07:34:49 -070022 void acquire() {
23 fSemaphore.wait();
herbe4c17352015-09-29 14:38:01 -070024 SkDEBUGCODE(fOwner = SkGetThreadID();)
herb7f0a3d72015-09-24 07:34:49 -070025 }
26
27 void release() {
28 this->assertHeld();
herbe4c17352015-09-29 14:38:01 -070029 SkDEBUGCODE(fOwner = kIllegalThreadID;)
herb7f0a3d72015-09-24 07:34:49 -070030 fSemaphore.signal();
31 }
32
33 void assertHeld() {
herbe4c17352015-09-29 14:38:01 -070034 SkASSERT(fOwner == SkGetThreadID());
herb7f0a3d72015-09-24 07:34:49 -070035 }
36
mtklein42846ed2016-05-05 10:57:37 -070037protected:
38 SkBaseSemaphore fSemaphore{1};
39 SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};)
sclittled9f5d202016-05-04 18:23:30 -070040};
41
sclittled9f5d202016-05-04 18:23:30 -070042class SkMutex : public SkBaseMutex {
43public:
Mike Klein3b7658a2017-09-20 09:53:39 -040044 using SkBaseMutex::SkBaseMutex;
45 ~SkMutex() { fSemaphore.cleanup(); }
herb7f0a3d72015-09-24 07:34:49 -070046};
mtkleina64c48f2015-01-21 13:13:31 -080047
mtkleinf10637f2016-06-10 13:56:35 -070048class SkAutoMutexAcquire {
mtkleina669bc72015-02-02 12:22:07 -080049public:
mtkleinf10637f2016-06-10 13:56:35 -070050 template <typename T>
51 SkAutoMutexAcquire(T* mutex) : fMutex(mutex) {
mtkleina669bc72015-02-02 12:22:07 -080052 if (mutex) {
53 mutex->acquire();
54 }
mtkleinf10637f2016-06-10 13:56:35 -070055 fRelease = [](void* mutex) { ((T*)mutex)->release(); };
mtkleina669bc72015-02-02 12:22:07 -080056 }
57
mtkleinf10637f2016-06-10 13:56:35 -070058 template <typename T>
59 SkAutoMutexAcquire(T& mutex) : SkAutoMutexAcquire(&mutex) {}
mtkleina669bc72015-02-02 12:22:07 -080060
mtkleinf10637f2016-06-10 13:56:35 -070061 ~SkAutoMutexAcquire() { this->release(); }
62
mtkleina669bc72015-02-02 12:22:07 -080063 void release() {
64 if (fMutex) {
mtkleinf10637f2016-06-10 13:56:35 -070065 fRelease(fMutex);
mtkleina669bc72015-02-02 12:22:07 -080066 }
mtkleinf10637f2016-06-10 13:56:35 -070067 fMutex = nullptr;
mtkleina669bc72015-02-02 12:22:07 -080068 }
69
70private:
mtkleinf10637f2016-06-10 13:56:35 -070071 void* fMutex;
72 void (*fRelease)(void*);
mtkleina669bc72015-02-02 12:22:07 -080073};
74#define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire)
75
mtkleinf10637f2016-06-10 13:56:35 -070076// SkAutoExclusive is a lighter weight version of SkAutoMutexAcquire.
77// It assumes that there is a valid mutex, obviating the null check.
78class SkAutoExclusive {
79public:
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
88private:
89 void* fMutex;
90 void (*fRelease)(void*);
91};
92#define SkAutoExclusive(...) SK_REQUIRE_LOCAL_VAR(SkAutoExclusive)
herb12449a92015-10-21 19:11:13 -070093
mtkleina64c48f2015-01-21 13:13:31 -080094#endif//SkMutex_DEFINED