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