OLD | NEW |
---|---|
1 // Copyright 2012 The Chromium Authors. All rights reserved. | 1 // Copyright 2012 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #ifndef SKIA_EXT_REFPTR_H_ | 5 #ifndef SKIA_EXT_REFPTR_H_ |
6 #define SKIA_EXT_REFPTR_H_ | 6 #define SKIA_EXT_REFPTR_H_ |
7 | 7 |
8 #include "base/basictypes.h" | |
9 #include "base/logging.h" | |
8 #include "third_party/skia/include/core/SkRefCnt.h" | 10 #include "third_party/skia/include/core/SkRefCnt.h" |
9 | 11 |
10 namespace skia { | 12 namespace skia { |
11 | 13 |
12 // When creating/receiving a ref-counted pointer from Skia, wrap that pointer in | 14 // When creating/receiving a ref-counted pointer from Skia, wrap that pointer in |
13 // this class to avoid dealing with the ref-counting and prevent leaks/crashes | 15 // this class to avoid dealing with the ref-counting and prevent leaks/crashes |
14 // due to ref-counting bugs. | 16 // due to ref-counting bugs. |
15 // | 17 // |
16 // Example of creating a new SkShader* and setting it on a SkPaint: | 18 // Example of creating a new SkShader* and setting it on a SkPaint: |
17 // skia::RefPtr<SkShader> shader = skia::AdoptRef(SkGradientShader::Create()); | 19 // skia::RefPtr<SkShader> shader = skia::AdoptRef(SkGradientShader::Create()); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
80 | 82 |
81 T* get() const { return ptr_; } | 83 T* get() const { return ptr_; } |
82 T& operator*() const { return *ptr_; } | 84 T& operator*() const { return *ptr_; } |
83 T* operator->() const { return ptr_; } | 85 T* operator->() const { return ptr_; } |
84 | 86 |
85 typedef T* RefPtr::*unspecified_bool_type; | 87 typedef T* RefPtr::*unspecified_bool_type; |
86 operator unspecified_bool_type() const { | 88 operator unspecified_bool_type() const { |
87 return ptr_ ? &RefPtr::ptr_ : NULL; | 89 return ptr_ ? &RefPtr::ptr_ : NULL; |
88 } | 90 } |
89 | 91 |
92 class Receiver { | |
93 public: | |
94 ~Receiver() { | |
95 DCHECK(!*refptr_) << "RefPtr must be empty."; | |
96 refptr_->ptr_ = ptr_; | |
97 } | |
98 | |
99 operator T**() { return &ptr_; } | |
100 | |
101 private: | |
102 friend class RefPtr; | |
103 | |
104 explicit Receiver(RefPtr* refptr) : refptr_(refptr), ptr_(NULL) { | |
105 DCHECK(!*refptr_) << "RefPtr must be empty."; | |
106 } | |
107 | |
108 RefPtr* refptr_; | |
109 T* ptr_; | |
110 | |
111 DISALLOW_COPY_AND_ASSIGN(Receiver); | |
112 }; | |
113 | |
114 // Call this and pass it to a function that takes a T** argument and | |
115 // sets it to an object with an unowned reference. | |
awong
2013/07/17 23:51:02
suggestion:
Call this and pass the returned tempor
| |
116 // NOTE: Do not use this function as part of a subexpression, and try to use | |
awong
2013/07/17 23:51:02
suggestion:
Do not use this function as part of a
danakj
2013/07/17 23:58:29
Thanks, will do.
I think that I can also DCHECK t
| |
117 // the RefPtr in the same subexpression, as this operation will not be | |
118 // complete and the RefPtr will be empty still. | |
119 // | |
120 // Bad (refptr will be NULL when it is dereffed): | |
121 // Foo(refptr.ReceiveAndAdoptRef()) && refptr->Bar(); | |
122 // Good: | |
123 // bool ok = Foo(refptr.ReceiveAndAdoptRef()); | |
124 // ok && refptr->Bar(); | |
125 Receiver ReceiveAndAdoptRef() { return Receiver(this); } | |
126 | |
90 private: | 127 private: |
91 T* ptr_; | 128 T* ptr_; |
92 | 129 |
93 // This function cannot be public because Skia starts its ref-counted | 130 // This function cannot be public because Skia starts its ref-counted |
94 // objects at refcnt=1. This makes it impossible to differentiate | 131 // objects at refcnt=1. This makes it impossible to differentiate |
95 // between a newly created object (that doesn't need to be ref'd) or an | 132 // between a newly created object (that doesn't need to be ref'd) or an |
96 // already existing object with one owner (that does need to be ref'd so that | 133 // already existing object with one owner (that does need to be ref'd so that |
97 // this RefPtr can also manage its lifetime). | 134 // this RefPtr can also manage its lifetime). |
98 explicit RefPtr(T* ptr) : ptr_(ptr) {} | 135 explicit RefPtr(T* ptr) : ptr_(ptr) {} |
99 | 136 |
100 template<typename U> | 137 template<typename U> |
101 friend RefPtr<U> AdoptRef(U* ptr); | 138 friend RefPtr<U> AdoptRef(U* ptr); |
102 | 139 |
103 template<typename U> | 140 template<typename U> |
104 friend RefPtr<U> SharePtr(U* ptr); | 141 friend RefPtr<U> SharePtr(U* ptr); |
105 }; | 142 }; |
106 | 143 |
107 // For objects that have an unowned reference (such as newly created objects). | 144 // For objects that have an unowned reference (such as newly created objects). |
108 template<typename T> | 145 template<typename T> |
109 RefPtr<T> AdoptRef(T* ptr) { return RefPtr<T>(ptr); } | 146 RefPtr<T> AdoptRef(T* ptr) { return RefPtr<T>(ptr); } |
110 | 147 |
111 // For objects that are already owned. This doesn't take ownership of existing | 148 // For objects that are already owned. This doesn't take ownership of existing |
112 // references and adds a new one. | 149 // references and adds a new one. |
113 template<typename T> | 150 template<typename T> |
114 RefPtr<T> SharePtr(T* ptr) { return RefPtr<T>(SkSafeRef(ptr)); } | 151 RefPtr<T> SharePtr(T* ptr) { return RefPtr<T>(SkSafeRef(ptr)); } |
115 | 152 |
116 } // namespace skia | 153 } // namespace skia |
117 | 154 |
118 #endif // SKIA_EXT_REFPTR_H_ | 155 #endif // SKIA_EXT_REFPTR_H_ |
OLD | NEW |