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// 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() {
31 SkAutoMutexExclusive lock(fMutex);
32 SkThreadID self = SkGetThreadID();
33 SkASSERT(fOwner == self || fOwner == kIllegalThreadID);
34 fReentranceCount++;
35 fOwner = self;
36 }
37
38 void exit() {
39 SkAutoMutexExclusive lock(fMutex);
40 SkASSERT(fOwner == SkGetThreadID());
41 fReentranceCount--;
42 if (fReentranceCount == 0) {
43 fOwner = kIllegalThreadID;
44 }
45 }
46
47 SkMutex fMutex;
48 SkThreadID fOwner SK_GUARDED_BY(fMutex);
49 int fReentranceCount SK_GUARDED_BY(fMutex);
50};
51#else
52class GrSingleOwner {}; // Provide a dummy implementation so we can pass pointers to constructors
53#endif
54
55#endif
56