Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(256)

Side by Side Diff: include/core/SkRefCnt.h

Issue 40503002: Allow users to build on top of, instead of beneath, SkRefCnt. (Closed) Base URL: http://skia.googlecode.com/svn/trunk/
Patch Set: Created 7 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « no previous file | src/core/SkRefCnt.cpp » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 1
2 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 9
10 #ifndef SkRefCnt_DEFINED 10 #ifndef SkRefCnt_DEFINED
11 #define SkRefCnt_DEFINED 11 #define SkRefCnt_DEFINED
12 12
13 #include "SkThread.h" 13 #include "SkThread.h"
14 #include "SkInstCnt.h" 14 #include "SkInstCnt.h"
15 #include "SkTemplates.h" 15 #include "SkTemplates.h"
16 16
17 #ifdef SK_REF_CNT_BASE_INCLUDE
18 #include SK_REF_CNT_BASE_INCLUDE
19 #else
20 /** \class SkRefCntBase 17 /** \class SkRefCntBase
21 18
22 Default implementation of SkRefCntBase. The base class' contract is to 19 SkRefCntBase is the base class for objects that may be shared by multiple
23 provide an implementation of aboutToRef. Embedders of skia can specify
24 an alternate implementation by setting SK_REF_CNT_BASE_INCLUDE. This is
25 useful for adding debug run-time checks to enforce certain usage patterns.
26 */
27 class SK_API SkRefCntBase {
28 public:
29 void aboutToRef() const {}
30 };
31 #endif
32
33 /** \class SkRefCnt
34
35 SkRefCnt is the base class for objects that may be shared by multiple
36 objects. When an existing owner wants to share a reference, it calls ref(). 20 objects. When an existing owner wants to share a reference, it calls ref().
37 When an owner wants to release its reference, it calls unref(). When the 21 When an owner wants to release its reference, it calls unref(). When the
38 shared object's reference count goes to zero as the result of an unref() 22 shared object's reference count goes to zero as the result of an unref()
39 call, its (virtual) destructor is called. It is an error for the 23 call, its (virtual) destructor is called. It is an error for the
40 destructor to be called explicitly (or via the object going out of scope on 24 destructor to be called explicitly (or via the object going out of scope on
41 the stack or calling delete) if getRefCnt() > 1. 25 the stack or calling delete) if getRefCnt() > 1.
42 */ 26 */
43 class SK_API SkRefCnt : public SkRefCntBase { 27 class SK_API SkRefCntBase : public SkNoncopyable {
44 public: 28 public:
45 SK_DECLARE_INST_COUNT_ROOT(SkRefCnt) 29 SK_DECLARE_INST_COUNT_ROOT(SkRefCntBase)
46 30
47 /** Default construct, initializing the reference count to 1. 31 /** Default construct, initializing the reference count to 1.
48 */ 32 */
49 SkRefCnt() : fRefCnt(1) {} 33 SkRefCntBase() : fRefCnt(1) {}
50 34
51 /** Destruct, asserting that the reference count is 1. 35 /** Destruct, asserting that the reference count is 1.
52 */ 36 */
53 virtual ~SkRefCnt() { 37 virtual ~SkRefCntBase() {
54 #ifdef SK_DEBUG 38 #ifdef SK_DEBUG
55 SkASSERT(fRefCnt == 1); 39 SkASSERT(fRefCnt == 1);
56 fRefCnt = 0; // illegal value, to catch us if we reuse after delete 40 fRefCnt = 0; // illegal value, to catch us if we reuse after delete
57 #endif 41 #endif
58 } 42 }
59 43
60 /** Return the reference count. Use only for debugging. */ 44 /** Return the reference count. Use only for debugging. */
61 int32_t getRefCnt() const { return fRefCnt; } 45 int32_t getRefCnt() const { return fRefCnt; }
62 46
63 /** Returns true if the caller is the only owner. 47 /** Returns true if the caller is the only owner.
64 * Ensures that all previous owner's actions are complete. 48 * Ensures that all previous owner's actions are complete.
65 */ 49 */
66 bool unique() const { 50 bool unique() const {
67 bool const unique = (1 == fRefCnt); 51 bool const unique = (1 == fRefCnt);
68 if (unique) { 52 if (unique) {
69 // Aquire barrier (L/SL), if not provided by load of fRefCnt. 53 // Aquire barrier (L/SL), if not provided by load of fRefCnt.
70 // Prevents user's 'unique' code from happening before decrements. 54 // Prevents user's 'unique' code from happening before decrements.
71 //TODO: issue the barrier. 55 //TODO: issue the barrier.
72 } 56 }
73 return unique; 57 return unique;
74 } 58 }
75 59
76 /** Increment the reference count. Must be balanced by a call to unref(). 60 /** Increment the reference count. Must be balanced by a call to unref().
77 */ 61 */
78 void ref() const { 62 void ref() const {
79 SkASSERT(fRefCnt > 0); 63 SkASSERT(fRefCnt > 0);
80 this->INHERITED::aboutToRef();
81 sk_atomic_inc(&fRefCnt); // No barrier required. 64 sk_atomic_inc(&fRefCnt); // No barrier required.
82 } 65 }
83 66
84 /** Decrement the reference count. If the reference count is 1 before the 67 /** Decrement the reference count. If the reference count is 1 before the
85 decrement, then delete the object. Note that if this is the case, then 68 decrement, then delete the object. Note that if this is the case, then
86 the object needs to have been allocated via new, and not on the stack. 69 the object needs to have been allocated via new, and not on the stack.
87 */ 70 */
88 void unref() const { 71 void unref() const {
89 SkASSERT(fRefCnt > 0); 72 SkASSERT(fRefCnt > 0);
90 // Release barrier (SL/S), if not provided below. 73 // Release barrier (SL/S), if not provided below.
91 if (sk_atomic_dec(&fRefCnt) == 1) { 74 if (sk_atomic_dec(&fRefCnt) == 1) {
92 // Aquire barrier (L/SL), if not provided above. 75 // Aquire barrier (L/SL), if not provided above.
93 // Prevents code in dispose from happening before the decrement. 76 // Prevents code in dispose from happening before the decrement.
94 sk_membar_aquire__after_atomic_dec(); 77 sk_membar_aquire__after_atomic_dec();
95 internal_dispose(); 78 internal_dispose();
96 } 79 }
97 } 80 }
98 81
99 #ifdef SK_DEBUG 82 #ifdef SK_DEBUG
100 void validate() const { 83 void validate() const {
101 SkASSERT(fRefCnt > 0); 84 SkASSERT(fRefCnt > 0);
102 } 85 }
103 #endif 86 #endif
104 87
105 /**
106 * Alias for unref(), for compatibility with WTF::RefPtr.
107 */
108 void deref() { this->unref(); }
109
110 protected: 88 protected:
111 /** 89 /**
112 * Allow subclasses to call this if they've overridden internal_dispose 90 * Allow subclasses to call this if they've overridden internal_dispose
113 * so they can reset fRefCnt before the destructor is called. Should only 91 * so they can reset fRefCnt before the destructor is called. Should only
114 * be called right before calling through to inherited internal_dispose() 92 * be called right before calling through to inherited internal_dispose()
115 * or before calling the destructor. 93 * or before calling the destructor.
116 */ 94 */
117 void internal_dispose_restore_refcnt_to_1() const { 95 void internal_dispose_restore_refcnt_to_1() const {
118 #ifdef SK_DEBUG 96 #ifdef SK_DEBUG
119 SkASSERT(0 == fRefCnt); 97 SkASSERT(0 == fRefCnt);
120 fRefCnt = 1; 98 fRefCnt = 1;
121 #endif 99 #endif
122 } 100 }
123 101
124 private: 102 private:
125 /** 103 /**
126 * Make SkRefCnt non-copyable.
127 */
128 SkRefCnt(const SkRefCnt&);
129 SkRefCnt& operator=(const SkRefCnt&);
130
131 /**
132 * Called when the ref count goes to 0. 104 * Called when the ref count goes to 0.
133 */ 105 */
134 virtual void internal_dispose() const { 106 virtual void internal_dispose() const {
135 this->internal_dispose_restore_refcnt_to_1(); 107 this->internal_dispose_restore_refcnt_to_1();
136 SkDELETE(this); 108 SkDELETE(this);
137 } 109 }
138 110
139 // The following friends are those which override internal_dispose() 111 // The following friends are those which override internal_dispose()
140 // and conditionally call SkRefCnt::internal_dispose(). 112 // and conditionally call SkRefCnt::internal_dispose().
141 friend class GrTexture; 113 friend class GrTexture;
142 friend class SkWeakRefCnt; 114 friend class SkWeakRefCnt;
143 115
144 mutable int32_t fRefCnt; 116 mutable int32_t fRefCnt;
145 117
146 typedef SkRefCntBase INHERITED; 118 typedef SkNoncopyable INHERITED;
147 }; 119 };
148 120
121 #ifdef SK_REF_CNT_MIXIN_INCLUDE
122 // It is the responsibility of the following include to define the type SkRefCnt .
123 // This SkRefCnt should normally derive from SkRefCntBase.
124 #include SK_REF_CNT_MIXIN_INCLUDE
125 #else
126 class SK_API SkRefCnt : public SkRefCntBase { };
127 #endif
128
149 /////////////////////////////////////////////////////////////////////////////// 129 ///////////////////////////////////////////////////////////////////////////////
150 130
151 /** Helper macro to safely assign one SkRefCnt[TS]* to another, checking for 131 /** Helper macro to safely assign one SkRefCnt[TS]* to another, checking for
152 null in on each side of the assignment, and ensuring that ref() is called 132 null in on each side of the assignment, and ensuring that ref() is called
153 before unref(), in case the two pointers point to the same object. 133 before unref(), in case the two pointers point to the same object.
154 */ 134 */
155 #define SkRefCnt_SafeAssign(dst, src) \ 135 #define SkRefCnt_SafeAssign(dst, src) \
156 do { \ 136 do { \
157 if (src) src->ref(); \ 137 if (src) src->ref(); \
158 if (dst) dst->unref(); \ 138 if (dst) dst->unref(); \
(...skipping 138 matching lines...) Expand 10 before | Expand all | Expand 10 after
297 typedef T* SkRefPtr::*unspecified_bool_type; 277 typedef T* SkRefPtr::*unspecified_bool_type;
298 operator unspecified_bool_type() const { 278 operator unspecified_bool_type() const {
299 return fObj ? &SkRefPtr::fObj : NULL; 279 return fObj ? &SkRefPtr::fObj : NULL;
300 } 280 }
301 281
302 private: 282 private:
303 T* fObj; 283 T* fObj;
304 }; 284 };
305 285
306 #endif 286 #endif
OLDNEW
« no previous file with comments | « no previous file | src/core/SkRefCnt.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698