• 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 GrSingleOwner_DEFINED
9 #define GrSingleOwner_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 
17 #define GR_ASSERT_SINGLE_OWNER(obj) \
18     GrSingleOwner::AutoEnforce debug_SingleOwner(obj, __FILE__, __LINE__);
19 
20 // This is a debug tool to verify an object is only being used from one thread at a time.
21 class GrSingleOwner {
22 public:
GrSingleOwner()23      GrSingleOwner() : fOwner(kIllegalThreadID), fReentranceCount(0) {}
24 
25      struct AutoEnforce {
AutoEnforceAutoEnforce26          AutoEnforce(GrSingleOwner* so, const char* file, int line)
27                 : fFile(file), fLine(line), fSO(so) {
28              fSO->enter(file, line);
29          }
~AutoEnforceAutoEnforce30          ~AutoEnforce() { fSO->exit(fFile, fLine); }
31 
32          const char* fFile;
33          int fLine;
34          GrSingleOwner* fSO;
35      };
36 
37 private:
enter(const char * file,int line)38      void enter(const char* file, int line) {
39          SkAutoMutexExclusive lock(fMutex);
40          SkThreadID self = SkGetThreadID();
41          SkASSERTF(fOwner == self || fOwner == kIllegalThreadID, "%s:%d Single owner failure.",
42                    file, line);
43          fReentranceCount++;
44          fOwner = self;
45      }
46 
exit(const char * file,int line)47      void exit(const char* file, int line) {
48          SkAutoMutexExclusive lock(fMutex);
49          SkASSERTF(fOwner == SkGetThreadID(), "%s:%d Single owner failure.", file, line);
50          fReentranceCount--;
51          if (fReentranceCount == 0) {
52              fOwner = kIllegalThreadID;
53          }
54      }
55 
56      SkMutex fMutex;
57      SkThreadID fOwner    SK_GUARDED_BY(fMutex);
58      int fReentranceCount SK_GUARDED_BY(fMutex);
59 };
60 #else
61 #define GR_ASSERT_SINGLE_OWNER(obj)
62 class GrSingleOwner {}; // Provide a no-op implementation so we can pass pointers to constructors
63 #endif
64 
65 #endif
66