• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2016 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 skgpu_SingleOwner_DEFINED
9 #define skgpu_SingleOwner_DEFINED
10 
11 #include "include/core/SkTypes.h"
12 
13 #ifdef SK_DEBUG
14 #include "include/private/SkMutex.h"
15 #include "include/private/SkThreadID.h"
16 #endif
17 
18 namespace skgpu {
19 
20 #ifdef SK_DEBUG
21 
22 #define SKGPU_ASSERT_SINGLE_OWNER(obj) \
23     skgpu::SingleOwner::AutoEnforce debug_SingleOwner(obj, __FILE__, __LINE__);
24 
25 // This is a debug tool to verify an object is only being used from one thread at a time.
26 class SingleOwner {
27 public:
SingleOwner()28      SingleOwner() : fOwner(kIllegalThreadID), fReentranceCount(0) {}
29 
30      struct AutoEnforce {
AutoEnforceAutoEnforce31          AutoEnforce(SingleOwner* so, const char* file, int line)
32                 : fFile(file), fLine(line), fSO(so) {
33              fSO->enter(file, line);
34          }
~AutoEnforceAutoEnforce35          ~AutoEnforce() { fSO->exit(fFile, fLine); }
36 
37          const char* fFile;
38          int fLine;
39          SingleOwner* fSO;
40      };
41 
42 private:
enter(const char * file,int line)43      void enter(const char* file, int line) {
44          SkAutoMutexExclusive lock(fMutex);
45          SkThreadID self = SkGetThreadID();
46          SkASSERTF(fOwner == self || fOwner == kIllegalThreadID, "%s:%d Single owner failure.",
47                    file, line);
48          fReentranceCount++;
49          fOwner = self;
50      }
51 
exit(const char * file,int line)52      void exit(const char* file, int line) {
53          SkAutoMutexExclusive lock(fMutex);
54          SkASSERTF(fOwner == SkGetThreadID(), "%s:%d Single owner failure.", file, line);
55          fReentranceCount--;
56          if (fReentranceCount == 0) {
57              fOwner = kIllegalThreadID;
58          }
59      }
60 
61      SkMutex fMutex;
62      SkThreadID fOwner    SK_GUARDED_BY(fMutex);
63      int fReentranceCount SK_GUARDED_BY(fMutex);
64 };
65 #else
66 #define SKGPU_ASSERT_SINGLE_OWNER(obj)
67 class SingleOwner {}; // Provide a no-op implementation so we can pass pointers to constructors
68 #endif
69 
70 } // namespace skgpu
71 
72 #endif
73