1 /* 2 Copyright 2010 Google Inc. 3 4 Licensed under the Apache License, Version 2.0 (the "License"); 5 you may not use this file except in compliance with the License. 6 You may obtain a copy of the License at 7 8 http://www.apache.org/licenses/LICENSE-2.0 9 10 Unless required by applicable law or agreed to in writing, software 11 distributed under the License is distributed on an "AS IS" BASIS, 12 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13 See the License for the specific language governing permissions and 14 limitations under the License. 15 */ 16 17 18 #ifndef GrRefCnt_DEFINED 19 #define GrRefCnt_DEFINED 20 21 #include "GrTypes.h" 22 #include "GrNoncopyable.h" 23 24 /** 25 * Base class for reference counting. When an object is first instantiated, 26 * its reference count is 1. If the object may be null, use GrSafeRef() and 27 * GrSafeUnref(). 28 * 29 * It is an error (though only checked for in the debug build) to call unref() 30 * such that the reference count becomes 0. 31 */ 32 class GR_API GrRefCnt : GrNoncopyable { 33 public: 34 GrRefCnt() : fRefCnt(1) {} 35 virtual ~GrRefCnt() { 36 GrAssert(1 == fRefCnt); 37 #if GR_DEBUG 38 fRefCnt = 0; // force validate() to trigger if called afterwards 39 #endif 40 } 41 42 int32_t refcnt() const { return fRefCnt; } 43 44 void ref() const { 45 GrAssert(fRefCnt > 0); 46 ++fRefCnt; 47 } 48 49 void unref() const { 50 GrAssert(fRefCnt > 0); 51 if (1 == fRefCnt) { 52 delete this; 53 } else { 54 --fRefCnt; 55 } 56 } 57 58 #if GR_DEBUG 59 void validate() const { 60 GrAssert(fRefCnt > 0); 61 } 62 #else 63 void validate() const {} 64 #endif 65 66 private: 67 mutable int32_t fRefCnt; 68 }; 69 70 /////////////////////////////////////////////////////////////////////////////// 71 72 /** 73 * Call with instance/subclass of GrRefCnt. This does nothing if obj is null, 74 * but otherwise it calls ref(). 75 */ 76 static inline void GrSafeRef(const GrRefCnt* obj) { 77 if (obj) { 78 obj->ref(); 79 } 80 } 81 82 /** 83 * Call with instance/subclass of GrRefCnt. This does nothing if obj is null, 84 * but otherwise it calls unref(). 85 */ 86 static inline void GrSafeUnref(const GrRefCnt* obj) { 87 if (obj) { 88 obj->unref(); 89 } 90 } 91 92 /** 93 * Assigns src to dst, checking for NULLs in each, and correctly incrementing 94 * the reference count of src, and decrementing the reference count of dst 95 */ 96 template<typename T> 97 static inline void GrSafeAssign(T*& dst, T* src) { 98 if (src) { 99 src->ref(); 100 } 101 if (dst) { 102 dst->unref(); 103 } 104 dst = src; 105 } 106 107 template<typename T> 108 static inline void GrSafeSetNull(T*& obj) { 109 if (NULL != obj) { 110 obj->unref(); 111 obj = NULL; 112 } 113 } 114 115 /////////////////////////////////////////////////////////////////////////////// 116 117 class GrAutoRef : GrNoncopyable { 118 public: 119 GrAutoRef(GrRefCnt* obj) : fObj(obj) { GrSafeRef(obj); } 120 ~GrAutoRef() { GrSafeUnref(fObj); } 121 private: 122 GrRefCnt* fObj; 123 }; 124 125 class GrAutoUnref : GrNoncopyable { 126 public: 127 GrAutoUnref(GrRefCnt* obj) : fObj(obj) {} 128 ~GrAutoUnref() { GrSafeUnref(fObj); } 129 private: 130 GrRefCnt* fObj; 131 }; 132 133 #endif 134 135