blob: 7cfdb1132c2f97a1795abc2728b0dcdbbccb3232 [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
herb7f0a3d72015-09-24 07:34:49 -070011#include "../private/SkSemaphore.h"
mtklein42846ed2016-05-05 10:57:37 -070012#include "../private/SkThreadID.h"
mtkleina64c48f2015-01-21 13:13:31 -080013#include "SkTypes.h"
14
mtklein42846ed2016-05-05 10:57:37 -070015#define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name;
reed086eea92016-05-04 17:12:46 -070016
mtklein42846ed2016-05-05 10:57:37 -070017class SkBaseMutex {
18public:
19 constexpr SkBaseMutex() = default;
herb7f0a3d72015-09-24 07:34:49 -070020
herb7f0a3d72015-09-24 07:34:49 -070021 void acquire() {
22 fSemaphore.wait();
herbe4c17352015-09-29 14:38:01 -070023 SkDEBUGCODE(fOwner = SkGetThreadID();)
herb7f0a3d72015-09-24 07:34:49 -070024 }
25
26 void release() {
27 this->assertHeld();
herbe4c17352015-09-29 14:38:01 -070028 SkDEBUGCODE(fOwner = kIllegalThreadID;)
herb7f0a3d72015-09-24 07:34:49 -070029 fSemaphore.signal();
30 }
31
32 void assertHeld() {
herbe4c17352015-09-29 14:38:01 -070033 SkASSERT(fOwner == SkGetThreadID());
herb7f0a3d72015-09-24 07:34:49 -070034 }
35
mtklein42846ed2016-05-05 10:57:37 -070036protected:
37 SkBaseSemaphore fSemaphore{1};
38 SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};)
sclittled9f5d202016-05-04 18:23:30 -070039};
40
sclittled9f5d202016-05-04 18:23:30 -070041class SkMutex : public SkBaseMutex {
42public:
mtklein42846ed2016-05-05 10:57:37 -070043 using SkBaseMutex::SkBaseMutex;
44 ~SkMutex() { fSemaphore.cleanup(); }
herb7f0a3d72015-09-24 07:34:49 -070045};
mtkleina64c48f2015-01-21 13:13:31 -080046
mtkleinf10637f2016-06-10 13:56:35 -070047class SkAutoMutexAcquire {
mtkleina669bc72015-02-02 12:22:07 -080048public:
mtkleinf10637f2016-06-10 13:56:35 -070049 template <typename T>
50 SkAutoMutexAcquire(T* mutex) : fMutex(mutex) {
mtkleina669bc72015-02-02 12:22:07 -080051 if (mutex) {
52 mutex->acquire();
53 }
mtkleinf10637f2016-06-10 13:56:35 -070054 fRelease = [](void* mutex) { ((T*)mutex)->release(); };
mtkleina669bc72015-02-02 12:22:07 -080055 }
56
mtkleinf10637f2016-06-10 13:56:35 -070057 template <typename T>
58 SkAutoMutexAcquire(T& mutex) : SkAutoMutexAcquire(&mutex) {}
mtkleina669bc72015-02-02 12:22:07 -080059
mtkleinf10637f2016-06-10 13:56:35 -070060 ~SkAutoMutexAcquire() { this->release(); }
61
mtkleina669bc72015-02-02 12:22:07 -080062 void release() {
63 if (fMutex) {
mtkleinf10637f2016-06-10 13:56:35 -070064 fRelease(fMutex);
mtkleina669bc72015-02-02 12:22:07 -080065 }
mtkleinf10637f2016-06-10 13:56:35 -070066 fMutex = nullptr;
mtkleina669bc72015-02-02 12:22:07 -080067 }
68
69private:
mtkleinf10637f2016-06-10 13:56:35 -070070 void* fMutex;
71 void (*fRelease)(void*);
mtkleina669bc72015-02-02 12:22:07 -080072};
73#define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire)
74
mtkleinf10637f2016-06-10 13:56:35 -070075// SkAutoExclusive is a lighter weight version of SkAutoMutexAcquire.
76// It assumes that there is a valid mutex, obviating the null check.
77class SkAutoExclusive {
78public:
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
87private:
88 void* fMutex;
89 void (*fRelease)(void*);
90};
91#define SkAutoExclusive(...) SK_REQUIRE_LOCAL_VAR(SkAutoExclusive)
herb12449a92015-10-21 19:11:13 -070092
mtkleina64c48f2015-01-21 13:13:31 -080093#endif//SkMutex_DEFINED