blob: 6369ae82c88dc54c844181a571ebd39d61c69bc7 [file] [log] [blame]
joshualitt1de610a2016-01-06 08:26:09 -08001/*
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
Mike Kleinc0bd9f92019-04-23 12:05:21 -050011#include "include/core/SkTypes.h"
joshualitt1de610a2016-01-06 08:26:09 -080012
13#ifdef SK_DEBUG
Mike Kleinc0bd9f92019-04-23 12:05:21 -050014#include "include/private/SkMutex.h"
15#include "include/private/SkThreadID.h"
joshualitt1de610a2016-01-06 08:26:09 -080016
17// This is a debug tool to verify an object is only being used from one thread at a time.
18class GrSingleOwner {
19public:
20 GrSingleOwner() : fOwner(kIllegalThreadID), fReentranceCount(0) {}
21
22 struct AutoEnforce {
23 AutoEnforce(GrSingleOwner* so) : fSO(so) { fSO->enter(); }
24 ~AutoEnforce() { fSO->exit(); }
25
26 GrSingleOwner* fSO;
27 };
28
29private:
30 void enter() {
Herb Derby9b869552019-05-10 12:16:17 -040031 SkAutoMutexExclusive lock(fMutex);
joshualitt1de610a2016-01-06 08:26:09 -080032 SkThreadID self = SkGetThreadID();
33 SkASSERT(fOwner == self || fOwner == kIllegalThreadID);
34 fReentranceCount++;
35 fOwner = self;
36 }
37
38 void exit() {
Herb Derby9b869552019-05-10 12:16:17 -040039 SkAutoMutexExclusive lock(fMutex);
joshualitt5b1dec72016-01-06 09:25:13 -080040 SkASSERT(fOwner == SkGetThreadID());
joshualitt1de610a2016-01-06 08:26:09 -080041 fReentranceCount--;
42 if (fReentranceCount == 0) {
43 fOwner = kIllegalThreadID;
44 }
45 }
46
47 SkMutex fMutex;
Herb Derby9b869552019-05-10 12:16:17 -040048 SkThreadID fOwner SK_GUARDED_BY(fMutex);
49 int fReentranceCount SK_GUARDED_BY(fMutex);
joshualitt1de610a2016-01-06 08:26:09 -080050};
joshualittde8dc7e2016-01-08 10:09:13 -080051#else
52class GrSingleOwner {}; // Provide a dummy implementation so we can pass pointers to constructors
joshualitt1de610a2016-01-06 08:26:09 -080053#endif
54
55#endif