1 /*
2 * Copyright (C) 2005 The Android Open Source Project
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 #ifndef ANDROID_STRONG_POINTER_H
18 #define ANDROID_STRONG_POINTER_H
19
20 #include <functional>
21 #include <type_traits> // for common_type.
22
23 // ---------------------------------------------------------------------------
24 namespace android {
25
26 template<typename T> class wp;
27
28 // ---------------------------------------------------------------------------
29
30 template<typename T>
31 class sp {
32 public:
sp()33 inline constexpr sp() : m_ptr(nullptr) { }
34
35 // The old way of using sp<> was like this. This is bad because it relies
36 // on implicit conversion to sp<>, which we would like to remove (if an
37 // object is being managed some other way, this is double-ownership). We
38 // want to move away from this:
39 //
40 // sp<Foo> foo = new Foo(...); // DO NOT DO THIS
41 //
42 // Instead, prefer to do this:
43 //
44 // sp<Foo> foo = sp<Foo>::make(...); // DO THIS
45 //
46 // Sometimes, in order to use this, when a constructor is marked as private,
47 // you may need to add this to your class:
48 //
49 // friend class sp<Foo>;
50 template <typename... Args>
51 static inline sp<T> make(Args&&... args);
52
53 // if nullptr, returns nullptr
54 //
55 // if a strong pointer is already available, this will retrieve it,
56 // otherwise, this will abort
57 static inline sp<T> fromExisting(T* other);
58
59 // for more information about this macro and correct RefBase usage, see
60 // the comment at the top of utils/RefBase.h
61 #if defined(ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION)
sp(std::nullptr_t)62 sp(std::nullptr_t) : sp() {}
63 #else
64 sp(T* other); // NOLINT(implicit)
65 template <typename U>
66 sp(U* other); // NOLINT(implicit)
67 sp& operator=(T* other);
68 template <typename U>
69 sp& operator=(U* other);
70 #endif
71
72 sp(const sp<T>& other);
73 sp(sp<T>&& other) noexcept;
74
75 template<typename U> sp(const sp<U>& other); // NOLINT(implicit)
76 template<typename U> sp(sp<U>&& other); // NOLINT(implicit)
77
78 // Cast a strong pointer directly from one type to another. Constructors
79 // allow changing types, but only if they are pointer-compatible. This does
80 // a static_cast internally.
81 template <typename U>
82 static inline sp<T> cast(const sp<U>& other);
83
84 ~sp();
85
86 // Assignment
87
88 sp& operator = (const sp<T>& other);
89 sp& operator=(sp<T>&& other) noexcept;
90
91 template<typename U> sp& operator = (const sp<U>& other);
92 template<typename U> sp& operator = (sp<U>&& other);
93
94 //! Special optimization for use by ProcessState (and nobody else).
95 void force_set(T* other);
96
97 // Reset
98
99 void clear();
100
101 // Releases the ownership of the object managed by this instance of sp, if any.
102 // The caller is now responsible for managing it. That is, the caller must ensure
103 // decStrong() is called when the pointer is no longer used.
release()104 [[nodiscard]] inline T* release() noexcept {
105 auto ret = m_ptr;
106 m_ptr = nullptr;
107 return ret;
108 }
109
110 // Accessors
111
112 inline T& operator* () const { return *m_ptr; }
113 inline T* operator-> () const { return m_ptr; }
get()114 inline T* get() const { return m_ptr; }
115 inline explicit operator bool () const { return m_ptr != nullptr; }
116
117 // Punt these to the wp<> implementation.
118 template<typename U>
119 inline bool operator == (const wp<U>& o) const {
120 return o == *this;
121 }
122
123 template<typename U>
124 inline bool operator != (const wp<U>& o) const {
125 return o != *this;
126 }
127
128 private:
129 template<typename Y> friend class sp;
130 template<typename Y> friend class wp;
131 void set_pointer(T* ptr);
132 T* m_ptr;
133 };
134
135 #define COMPARE_STRONG(_op_) \
136 template <typename T, typename U> \
137 static inline bool operator _op_(const sp<T>& t, const sp<U>& u) { \
138 return t.get() _op_ u.get(); \
139 } \
140 template <typename T, typename U> \
141 static inline bool operator _op_(const T* t, const sp<U>& u) { \
142 return t _op_ u.get(); \
143 } \
144 template <typename T, typename U> \
145 static inline bool operator _op_(const sp<T>& t, const U* u) { \
146 return t.get() _op_ u; \
147 } \
148 template <typename T> \
149 static inline bool operator _op_(const sp<T>& t, std::nullptr_t) { \
150 return t.get() _op_ nullptr; \
151 } \
152 template <typename T> \
153 static inline bool operator _op_(std::nullptr_t, const sp<T>& t) { \
154 return nullptr _op_ t.get(); \
155 }
156
157 template <template <typename C> class comparator, typename T, typename U>
_sp_compare_(T * a,U * b)158 static inline bool _sp_compare_(T* a, U* b) {
159 return comparator<typename std::common_type<T*, U*>::type>()(a, b);
160 }
161
162 #define COMPARE_STRONG_FUNCTIONAL(_op_, _compare_) \
163 template <typename T, typename U> \
164 static inline bool operator _op_(const sp<T>& t, const sp<U>& u) { \
165 return _sp_compare_<_compare_>(t.get(), u.get()); \
166 } \
167 template <typename T, typename U> \
168 static inline bool operator _op_(const T* t, const sp<U>& u) { \
169 return _sp_compare_<_compare_>(t, u.get()); \
170 } \
171 template <typename T, typename U> \
172 static inline bool operator _op_(const sp<T>& t, const U* u) { \
173 return _sp_compare_<_compare_>(t.get(), u); \
174 } \
175 template <typename T> \
176 static inline bool operator _op_(const sp<T>& t, std::nullptr_t) { \
177 return _sp_compare_<_compare_>(t.get(), nullptr); \
178 } \
179 template <typename T> \
180 static inline bool operator _op_(std::nullptr_t, const sp<T>& t) { \
181 return _sp_compare_<_compare_>(nullptr, t.get()); \
182 }
183
184 COMPARE_STRONG(==)
185 COMPARE_STRONG(!=)
186 COMPARE_STRONG_FUNCTIONAL(>, std::greater)
187 COMPARE_STRONG_FUNCTIONAL(<, std::less)
188 COMPARE_STRONG_FUNCTIONAL(<=, std::less_equal)
189 COMPARE_STRONG_FUNCTIONAL(>=, std::greater_equal)
190
191 #undef COMPARE_STRONG
192 #undef COMPARE_STRONG_FUNCTIONAL
193
194 // For code size reasons, we do not want these inlined or templated.
195 void sp_report_race();
196
197 // ---------------------------------------------------------------------------
198 // No user serviceable parts below here.
199
200 // TODO: Ideally we should find a way to increment the reference count before running the
201 // constructor, so that generating an sp<> to this in the constructor is no longer dangerous.
202 template <typename T>
203 template <typename... Args>
make(Args &&...args)204 sp<T> sp<T>::make(Args&&... args) {
205 T* t = new T(std::forward<Args>(args)...);
206 sp<T> result;
207 result.m_ptr = t;
208 t->incStrong(t);
209 return result;
210 }
211
212 template <typename T>
fromExisting(T * other)213 sp<T> sp<T>::fromExisting(T* other) {
214 if (other) {
215 other->incStrongRequireStrong(other);
216 sp<T> result;
217 result.m_ptr = other;
218 return result;
219 }
220 return nullptr;
221 }
222
223 #if !defined(ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION)
224 template<typename T>
sp(T * other)225 sp<T>::sp(T* other)
226 : m_ptr(other) {
227 if (other) {
228 other->incStrong(this);
229 }
230 }
231
232 template <typename T>
233 template <typename U>
sp(U * other)234 sp<T>::sp(U* other) : m_ptr(other) {
235 if (other) {
236 (static_cast<T*>(other))->incStrong(this);
237 }
238 }
239
240 template <typename T>
241 sp<T>& sp<T>::operator=(T* other) {
242 T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
243 if (other) {
244 other->incStrong(this);
245 }
246 if (oldPtr) oldPtr->decStrong(this);
247 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
248 m_ptr = other;
249 return *this;
250 }
251 #endif
252
253 template<typename T>
sp(const sp<T> & other)254 sp<T>::sp(const sp<T>& other)
255 : m_ptr(other.m_ptr) {
256 if (m_ptr)
257 m_ptr->incStrong(this);
258 }
259
260 template <typename T>
sp(sp<T> && other)261 sp<T>::sp(sp<T>&& other) noexcept : m_ptr(other.m_ptr) {
262 other.m_ptr = nullptr;
263 }
264
265 template<typename T> template<typename U>
sp(const sp<U> & other)266 sp<T>::sp(const sp<U>& other)
267 : m_ptr(other.m_ptr) {
268 if (m_ptr)
269 m_ptr->incStrong(this);
270 }
271
272 template<typename T> template<typename U>
sp(sp<U> && other)273 sp<T>::sp(sp<U>&& other)
274 : m_ptr(other.m_ptr) {
275 other.m_ptr = nullptr;
276 }
277
278 template <typename T>
279 template <typename U>
cast(const sp<U> & other)280 sp<T> sp<T>::cast(const sp<U>& other) {
281 return sp<T>::fromExisting(static_cast<T*>(other.get()));
282 }
283
284 template<typename T>
~sp()285 sp<T>::~sp() {
286 if (m_ptr)
287 m_ptr->decStrong(this);
288 }
289
290 template<typename T>
291 sp<T>& sp<T>::operator =(const sp<T>& other) {
292 // Force m_ptr to be read twice, to heuristically check for data races.
293 T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
294 T* otherPtr(other.m_ptr);
295 if (otherPtr) otherPtr->incStrong(this);
296 if (oldPtr) oldPtr->decStrong(this);
297 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
298 m_ptr = otherPtr;
299 return *this;
300 }
301
302 template <typename T>
303 sp<T>& sp<T>::operator=(sp<T>&& other) noexcept {
304 T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
305 if (oldPtr) oldPtr->decStrong(this);
306 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
307 m_ptr = other.m_ptr;
308 other.m_ptr = nullptr;
309 return *this;
310 }
311
312 template<typename T> template<typename U>
313 sp<T>& sp<T>::operator =(const sp<U>& other) {
314 T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
315 T* otherPtr(other.m_ptr);
316 if (otherPtr) otherPtr->incStrong(this);
317 if (oldPtr) oldPtr->decStrong(this);
318 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
319 m_ptr = otherPtr;
320 return *this;
321 }
322
323 template<typename T> template<typename U>
324 sp<T>& sp<T>::operator =(sp<U>&& other) {
325 T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
326 if (m_ptr) m_ptr->decStrong(this);
327 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
328 m_ptr = other.m_ptr;
329 other.m_ptr = nullptr;
330 return *this;
331 }
332
333 #if !defined(ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION)
334 template<typename T> template<typename U>
335 sp<T>& sp<T>::operator =(U* other) {
336 T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
337 if (other) (static_cast<T*>(other))->incStrong(this);
338 if (oldPtr) oldPtr->decStrong(this);
339 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
340 m_ptr = other;
341 return *this;
342 }
343 #endif
344
345 template<typename T>
force_set(T * other)346 void sp<T>::force_set(T* other) {
347 other->forceIncStrong(this);
348 m_ptr = other;
349 }
350
351 template<typename T>
clear()352 void sp<T>::clear() {
353 T* oldPtr(*const_cast<T* volatile*>(&m_ptr));
354 if (oldPtr) {
355 oldPtr->decStrong(this);
356 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race();
357 m_ptr = nullptr;
358 }
359 }
360
361 template<typename T>
set_pointer(T * ptr)362 void sp<T>::set_pointer(T* ptr) {
363 m_ptr = ptr;
364 }
365
366 } // namespace android
367
368 // ---------------------------------------------------------------------------
369
370 #endif // ANDROID_STRONG_POINTER_H
371