Index: include/private/SkMutex.h |
diff --git a/include/private/SkMutex.h b/include/private/SkMutex.h |
index b9af00f8a8be02fc1e3b7794e23d761b1c94c761..8c78e1205c8796261be4b19468338a00af8afdc5 100644 |
--- a/include/private/SkMutex.h |
+++ b/include/private/SkMutex.h |
@@ -8,20 +8,33 @@ |
#ifndef SkMutex_DEFINED |
#define SkMutex_DEFINED |
+// This file is not part of the public Skia API. |
#include "../private/SkSemaphore.h" |
-#include "../private/SkThreadID.h" |
#include "SkTypes.h" |
-// TODO: no need for this anymore. |
-#define SK_DECLARE_STATIC_MUTEX(name) static SkMutex name; |
+#ifdef SK_DEBUG |
+ #include "../private/SkThreadID.h" |
+#endif |
-class SkMutex { |
-public: |
- constexpr SkMutex() = default; |
+#define SK_MUTEX_SEMAPHORE_INIT {1, {0}} |
- SkMutex(const SkMutex&) = delete; |
- SkMutex& operator=(const SkMutex&) = delete; |
+#ifdef SK_DEBUG |
+ #define SK_BASE_MUTEX_INIT {SK_MUTEX_SEMAPHORE_INIT, 0} |
+#else |
+ #define SK_BASE_MUTEX_INIT {SK_MUTEX_SEMAPHORE_INIT} |
+#endif |
+// Using POD-style initialization prevents the generation of a static initializer. |
+// |
+// Without magic statics there are no thread safety guarantees on initialization |
+// of local statics (even POD). As a result, it is illegal to use |
+// SK_DECLARE_STATIC_MUTEX in a function. |
+// |
+// Because SkBaseMutex is not a primitive, a static SkBaseMutex cannot be |
+// initialized in a class with this macro. |
+#define SK_DECLARE_STATIC_MUTEX(name) namespace {} static SkBaseMutex name = SK_BASE_MUTEX_INIT; |
+ |
+struct SkBaseMutex { |
void acquire() { |
fSemaphore.wait(); |
SkDEBUGCODE(fOwner = SkGetThreadID();) |
@@ -37,9 +50,20 @@ |
SkASSERT(fOwner == SkGetThreadID()); |
} |
-private: |
- SkSemaphore fSemaphore{1}; |
- SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};) |
+ SkBaseSemaphore fSemaphore; |
+ SkDEBUGCODE(SkThreadID fOwner;) |
+}; |
+ |
+// This needs to use subclassing instead of encapsulation to make SkAutoMutexAcquire to work. |
+class SkMutex : public SkBaseMutex { |
+public: |
+ SkMutex () { |
+ fSemaphore = SK_MUTEX_SEMAPHORE_INIT; |
+ SkDEBUGCODE(fOwner = kIllegalThreadID); |
+ } |
+ ~SkMutex () { fSemaphore.deleteSemaphore(); } |
+ SkMutex(const SkMutex&) = delete; |
+ SkMutex& operator=(const SkMutex&) = delete; |
}; |
template <typename Lock> |
@@ -92,10 +116,10 @@ |
Lock &fLock; |
}; |
-typedef SkAutoTAcquire<SkMutex> SkAutoMutexAcquire; |
+typedef SkAutoTAcquire<SkBaseMutex> SkAutoMutexAcquire; |
#define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire) |
-typedef SkAutoTExclusive<SkMutex> SkAutoMutexExclusive; |
+typedef SkAutoTExclusive<SkBaseMutex> SkAutoMutexExclusive; |
#define SkAutoMutexExclusive(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexExclusive) |
#endif//SkMutex_DEFINED |