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 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 // Accessors 102 103 inline T& operator* () const { return *m_ptr; } 104 inline T* operator-> () const { return m_ptr; } get()105 inline T* get() const { return m_ptr; } 106 inline explicit operator bool () const { return m_ptr != nullptr; } 107 108 // Punt these to the wp<> implementation. 109 template<typename U> 110 inline bool operator == (const wp<U>& o) const { 111 return o == *this; 112 } 113 114 template<typename U> 115 inline bool operator != (const wp<U>& o) const { 116 return o != *this; 117 } 118 119 private: 120 template<typename Y> friend class sp; 121 template<typename Y> friend class wp; 122 void set_pointer(T* ptr); 123 T* m_ptr; 124 }; 125 126 #define COMPARE_STRONG(_op_) \ 127 template <typename T, typename U> \ 128 static inline bool operator _op_(const sp<T>& t, const sp<U>& u) { \ 129 return t.get() _op_ u.get(); \ 130 } \ 131 template <typename T, typename U> \ 132 static inline bool operator _op_(const T* t, const sp<U>& u) { \ 133 return t _op_ u.get(); \ 134 } \ 135 template <typename T, typename U> \ 136 static inline bool operator _op_(const sp<T>& t, const U* u) { \ 137 return t.get() _op_ u; \ 138 } \ 139 template <typename T> \ 140 static inline bool operator _op_(const sp<T>& t, std::nullptr_t) { \ 141 return t.get() _op_ nullptr; \ 142 } \ 143 template <typename T> \ 144 static inline bool operator _op_(std::nullptr_t, const sp<T>& t) { \ 145 return nullptr _op_ t.get(); \ 146 } 147 148 template <template <typename C> class comparator, typename T, typename U> _sp_compare_(T * a,U * b)149 static inline bool _sp_compare_(T* a, U* b) { 150 return comparator<typename std::common_type<T*, U*>::type>()(a, b); 151 } 152 153 #define COMPARE_STRONG_FUNCTIONAL(_op_, _compare_) \ 154 template <typename T, typename U> \ 155 static inline bool operator _op_(const sp<T>& t, const sp<U>& u) { \ 156 return _sp_compare_<_compare_>(t.get(), u.get()); \ 157 } \ 158 template <typename T, typename U> \ 159 static inline bool operator _op_(const T* t, const sp<U>& u) { \ 160 return _sp_compare_<_compare_>(t, u.get()); \ 161 } \ 162 template <typename T, typename U> \ 163 static inline bool operator _op_(const sp<T>& t, const U* u) { \ 164 return _sp_compare_<_compare_>(t.get(), u); \ 165 } \ 166 template <typename T> \ 167 static inline bool operator _op_(const sp<T>& t, std::nullptr_t) { \ 168 return _sp_compare_<_compare_>(t.get(), nullptr); \ 169 } \ 170 template <typename T> \ 171 static inline bool operator _op_(std::nullptr_t, const sp<T>& t) { \ 172 return _sp_compare_<_compare_>(nullptr, t.get()); \ 173 } 174 175 COMPARE_STRONG(==) 176 COMPARE_STRONG(!=) 177 COMPARE_STRONG_FUNCTIONAL(>, std::greater) 178 COMPARE_STRONG_FUNCTIONAL(<, std::less) 179 COMPARE_STRONG_FUNCTIONAL(<=, std::less_equal) 180 COMPARE_STRONG_FUNCTIONAL(>=, std::greater_equal) 181 182 #undef COMPARE_STRONG 183 #undef COMPARE_STRONG_FUNCTIONAL 184 185 // For code size reasons, we do not want these inlined or templated. 186 void sp_report_race(); 187 188 // --------------------------------------------------------------------------- 189 // No user serviceable parts below here. 190 191 // TODO: Ideally we should find a way to increment the reference count before running the 192 // constructor, so that generating an sp<> to this in the constructor is no longer dangerous. 193 template <typename T> 194 template <typename... Args> make(Args &&...args)195 sp<T> sp<T>::make(Args&&... args) { 196 T* t = new T(std::forward<Args>(args)...); 197 sp<T> result; 198 result.m_ptr = t; 199 t->incStrong(t); 200 return result; 201 } 202 203 template <typename T> fromExisting(T * other)204 sp<T> sp<T>::fromExisting(T* other) { 205 if (other) { 206 other->incStrongRequireStrong(other); 207 sp<T> result; 208 result.m_ptr = other; 209 return result; 210 } 211 return nullptr; 212 } 213 214 #if !defined(ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION) 215 template<typename T> sp(T * other)216 sp<T>::sp(T* other) 217 : m_ptr(other) { 218 if (other) { 219 other->incStrong(this); 220 } 221 } 222 223 template <typename T> 224 template <typename U> sp(U * other)225 sp<T>::sp(U* other) : m_ptr(other) { 226 if (other) { 227 (static_cast<T*>(other))->incStrong(this); 228 } 229 } 230 231 template <typename T> 232 sp<T>& sp<T>::operator=(T* other) { 233 T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); 234 if (other) { 235 other->incStrong(this); 236 } 237 if (oldPtr) oldPtr->decStrong(this); 238 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); 239 m_ptr = other; 240 return *this; 241 } 242 #endif 243 244 template<typename T> sp(const sp<T> & other)245 sp<T>::sp(const sp<T>& other) 246 : m_ptr(other.m_ptr) { 247 if (m_ptr) 248 m_ptr->incStrong(this); 249 } 250 251 template <typename T> sp(sp<T> && other)252 sp<T>::sp(sp<T>&& other) noexcept : m_ptr(other.m_ptr) { 253 other.m_ptr = nullptr; 254 } 255 256 template<typename T> template<typename U> sp(const sp<U> & other)257 sp<T>::sp(const sp<U>& other) 258 : m_ptr(other.m_ptr) { 259 if (m_ptr) 260 m_ptr->incStrong(this); 261 } 262 263 template<typename T> template<typename U> sp(sp<U> && other)264 sp<T>::sp(sp<U>&& other) 265 : m_ptr(other.m_ptr) { 266 other.m_ptr = nullptr; 267 } 268 269 template <typename T> 270 template <typename U> cast(const sp<U> & other)271 sp<T> sp<T>::cast(const sp<U>& other) { 272 return sp<T>::fromExisting(static_cast<T*>(other.get())); 273 } 274 275 template<typename T> ~sp()276 sp<T>::~sp() { 277 if (m_ptr) 278 m_ptr->decStrong(this); 279 } 280 281 template<typename T> 282 sp<T>& sp<T>::operator =(const sp<T>& other) { 283 // Force m_ptr to be read twice, to heuristically check for data races. 284 T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); 285 T* otherPtr(other.m_ptr); 286 if (otherPtr) otherPtr->incStrong(this); 287 if (oldPtr) oldPtr->decStrong(this); 288 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); 289 m_ptr = otherPtr; 290 return *this; 291 } 292 293 template <typename T> 294 sp<T>& sp<T>::operator=(sp<T>&& other) noexcept { 295 T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); 296 if (oldPtr) oldPtr->decStrong(this); 297 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); 298 m_ptr = other.m_ptr; 299 other.m_ptr = nullptr; 300 return *this; 301 } 302 303 template<typename T> template<typename U> 304 sp<T>& sp<T>::operator =(const sp<U>& other) { 305 T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); 306 T* otherPtr(other.m_ptr); 307 if (otherPtr) otherPtr->incStrong(this); 308 if (oldPtr) oldPtr->decStrong(this); 309 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); 310 m_ptr = otherPtr; 311 return *this; 312 } 313 314 template<typename T> template<typename U> 315 sp<T>& sp<T>::operator =(sp<U>&& other) { 316 T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); 317 if (m_ptr) m_ptr->decStrong(this); 318 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); 319 m_ptr = other.m_ptr; 320 other.m_ptr = nullptr; 321 return *this; 322 } 323 324 #if !defined(ANDROID_UTILS_REF_BASE_DISABLE_IMPLICIT_CONSTRUCTION) 325 template<typename T> template<typename U> 326 sp<T>& sp<T>::operator =(U* other) { 327 T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); 328 if (other) (static_cast<T*>(other))->incStrong(this); 329 if (oldPtr) oldPtr->decStrong(this); 330 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); 331 m_ptr = other; 332 return *this; 333 } 334 #endif 335 336 template<typename T> force_set(T * other)337 void sp<T>::force_set(T* other) { 338 other->forceIncStrong(this); 339 m_ptr = other; 340 } 341 342 template<typename T> clear()343 void sp<T>::clear() { 344 T* oldPtr(*const_cast<T* volatile*>(&m_ptr)); 345 if (oldPtr) { 346 oldPtr->decStrong(this); 347 if (oldPtr != *const_cast<T* volatile*>(&m_ptr)) sp_report_race(); 348 m_ptr = nullptr; 349 } 350 } 351 352 template<typename T> set_pointer(T * ptr)353 void sp<T>::set_pointer(T* ptr) { 354 m_ptr = ptr; 355 } 356 357 } // namespace android 358 359 // --------------------------------------------------------------------------- 360 361 #endif // ANDROID_STRONG_POINTER_H 362