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