SkMutex.h 2.1 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394
  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. #ifndef SkMutex_DEFINED
  8. #define SkMutex_DEFINED
  9. #include "../private/SkMacros.h"
  10. #include "../private/SkSemaphore.h"
  11. #include "../private/SkThreadID.h"
  12. #include "SkTypes.h"
  13. #define SK_DECLARE_STATIC_MUTEX(name) static SkBaseMutex name;
  14. class SkBaseMutex {
  15. public:
  16. constexpr SkBaseMutex() = default;
  17. void acquire() {
  18. fSemaphore.wait();
  19. SkDEBUGCODE(fOwner = SkGetThreadID();)
  20. }
  21. void release() {
  22. this->assertHeld();
  23. SkDEBUGCODE(fOwner = kIllegalThreadID;)
  24. fSemaphore.signal();
  25. }
  26. void assertHeld() {
  27. SkASSERT(fOwner == SkGetThreadID());
  28. }
  29. protected:
  30. SkBaseSemaphore fSemaphore{1};
  31. SkDEBUGCODE(SkThreadID fOwner{kIllegalThreadID};)
  32. };
  33. class SkMutex : public SkBaseMutex {
  34. public:
  35. using SkBaseMutex::SkBaseMutex;
  36. ~SkMutex() { fSemaphore.cleanup(); }
  37. };
  38. class SkAutoMutexAcquire {
  39. public:
  40. template <typename T>
  41. SkAutoMutexAcquire(T* mutex) : fMutex(mutex) {
  42. if (mutex) {
  43. mutex->acquire();
  44. }
  45. fRelease = [](void* mutex) { ((T*)mutex)->release(); };
  46. }
  47. template <typename T>
  48. SkAutoMutexAcquire(T& mutex) : SkAutoMutexAcquire(&mutex) {}
  49. ~SkAutoMutexAcquire() { this->release(); }
  50. void release() {
  51. if (fMutex) {
  52. fRelease(fMutex);
  53. }
  54. fMutex = nullptr;
  55. }
  56. private:
  57. void* fMutex;
  58. void (*fRelease)(void*);
  59. };
  60. #define SkAutoMutexAcquire(...) SK_REQUIRE_LOCAL_VAR(SkAutoMutexAcquire)
  61. // SkAutoExclusive is a lighter weight version of SkAutoMutexAcquire.
  62. // It assumes that there is a valid mutex, obviating the null check.
  63. class SkAutoExclusive {
  64. public:
  65. template <typename T>
  66. SkAutoExclusive(T& mutex) : fMutex(&mutex) {
  67. mutex.acquire();
  68. fRelease = [](void* mutex) { ((T*)mutex)->release(); };
  69. }
  70. ~SkAutoExclusive() { fRelease(fMutex); }
  71. private:
  72. void* fMutex;
  73. void (*fRelease)(void*);
  74. };
  75. #define SkAutoExclusive(...) SK_REQUIRE_LOCAL_VAR(SkAutoExclusive)
  76. #endif//SkMutex_DEFINED