• 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 #if defined(SK_DEBUG) || defined(SKIA_OHOS_SINGLE_OWNER)
14 #include "include/private/SkMutex.h"
15 #include "include/private/SkThreadID.h"
16 
17 #ifdef SKIA_OHOS_SINGLE_OWNER
18 #include <thread>
19 #include <string>
20 #include <sstream>
21 #include "include/core/SkLog.h"
22 #include <csignal>
23 #endif
24 
25 
26 #define GR_ASSERT_SINGLE_OWNER(obj) \
27     GrSingleOwner::AutoEnforce debug_SingleOwner(obj, __FILE__, __LINE__);
28 
29 static const int SIGNO_FOR_OCEAN = 42;
30 // This is a debug tool to verify an object is only being used from one thread at a time.
31 class GrSingleOwner {
32 public:
GrSingleOwner()33      GrSingleOwner() : fOwner(kIllegalThreadID), fReentranceCount(0) {}
34 
35      struct AutoEnforce {
AutoEnforceAutoEnforce36          AutoEnforce(GrSingleOwner* so, const char* file, int line)
37                 : fFile(file), fLine(line), fSO(so) {
38              fSO->enter(file, line);
39          }
~AutoEnforceAutoEnforce40          ~AutoEnforce() { fSO->exit(fFile, fLine); }
41 
42          const char* fFile;
43          int fLine;
44          GrSingleOwner* fSO;
45      };
46 
47 private:
enter(const char * file,int line)48      void enter(const char* file, int line) {
49 #ifdef SKIA_OHOS_SINGLE_OWNER
50          if (!GetEnableSkiaSingleOwner()) {
51             return;
52          }
53 #endif
54          SkAutoMutexExclusive lock(fMutex);
55          SkThreadID self = SkGetThreadID();
56 #ifdef SKIA_OHOS_SINGLE_OWNER
57          bool assertCheck = (fOwner == self || fOwner == kIllegalThreadID);
58          if (!assertCheck) {
59             SK_LOGE("\n\n\n\n ========== BackTrace Start ==========");
60             PrintBackTrace(fOwnerTid);
61             SK_LOGE("========== BackTrace End ========== occur file:%{public}s line:%{public}d\n\n\n\n",
62                 file, line);
63             raise(SIGNO_FOR_OCEAN); // report to Ocean
64          }
65          fReentranceCount++;
66          fOwner = self;
67          fOwnerTid = gettid();
68 #else
69          SkASSERTF(fOwner == self || fOwner == kIllegalThreadID, "%s:%d Single owner failure.",
70                    file, line);
71          fReentranceCount++;
72          fOwner = self;
73 #endif
74      }
75 
exit(const char * file,int line)76      void exit(const char* file, int line) {
77 #ifdef SKIA_OHOS_SINGLE_OWNER
78          if (!GetEnableSkiaSingleOwner()) {
79             return;
80          }
81 #endif
82          SkAutoMutexExclusive lock(fMutex);
83 #ifdef SKIA_OHOS_SINGLE_OWNER
84          SkThreadID self = SkGetThreadID();
85          bool assertCheck = (fOwner == self || fOwner == kIllegalThreadID);
86          if (!assertCheck) {
87             SK_LOGE("\n\n\n\n ========== BackTrace Start ==========");
88             PrintBackTrace(fOwnerTid);
89             SK_LOGE("========== BackTrace End ========== occur file:%{public}s line:%{public}d\n\n\n\n",
90                 file, line);
91             raise(SIGNO_FOR_OCEAN); // report to Ocean
92          }
93          fReentranceCount--;
94          if (fReentranceCount <= 0) {
95              fOwner = kIllegalThreadID;
96              fOwnerTid = 0;
97          }
98 #else
99          SkASSERTF(fOwner == SkGetThreadID(), "%s:%d Single owner failure.", file, line);
100          fReentranceCount--;
101          if (fReentranceCount == 0) {
102              fOwner = kIllegalThreadID;
103          }
104 #endif
105      }
106 
107 #ifdef SKIA_OHOS_SINGLE_OWNER
108      pid_t fOwnerTid SK_GUARDED_BY(fMutex);
109 #endif
110      SkMutex fMutex;
111      SkThreadID fOwner    SK_GUARDED_BY(fMutex);
112      int fReentranceCount SK_GUARDED_BY(fMutex);
113 };
114 #else
115 #define GR_ASSERT_SINGLE_OWNER(obj)
116 class GrSingleOwner {}; // Provide a no-op implementation so we can pass pointers to constructors
117 #endif
118 
119 #endif
120