• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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_REF_BASE_H
18 #define ANDROID_REF_BASE_H
19 
20 #include <cutils/atomic.h>
21 #include <utils/TextOutput.h>
22 
23 #include <stdint.h>
24 #include <sys/types.h>
25 #include <stdlib.h>
26 
27 // ---------------------------------------------------------------------------
28 namespace android {
29 
30 template<typename T> class wp;
31 
32 // ---------------------------------------------------------------------------
33 
34 #define COMPARE_WEAK(_op_)                                      \
35 inline bool operator _op_ (const sp<T>& o) const {              \
36     return m_ptr _op_ o.m_ptr;                                  \
37 }                                                               \
38 inline bool operator _op_ (const T* o) const {                  \
39     return m_ptr _op_ o;                                        \
40 }                                                               \
41 template<typename U>                                            \
42 inline bool operator _op_ (const sp<U>& o) const {              \
43     return m_ptr _op_ o.m_ptr;                                  \
44 }                                                               \
45 template<typename U>                                            \
46 inline bool operator _op_ (const U* o) const {                  \
47     return m_ptr _op_ o;                                        \
48 }
49 
50 #define COMPARE(_op_)                                           \
51 COMPARE_WEAK(_op_)                                              \
52 inline bool operator _op_ (const wp<T>& o) const {              \
53     return m_ptr _op_ o.m_ptr;                                  \
54 }                                                               \
55 template<typename U>                                            \
56 inline bool operator _op_ (const wp<U>& o) const {              \
57     return m_ptr _op_ o.m_ptr;                                  \
58 }
59 
60 // ---------------------------------------------------------------------------
61 
62 class RefBase
63 {
64 public:
65             void            incStrong(const void* id) const;
66             void            decStrong(const void* id) const;
67 
68             void            forceIncStrong(const void* id) const;
69 
70             //! DEBUGGING ONLY: Get current strong ref count.
71             int32_t         getStrongCount() const;
72 
73     class weakref_type
74     {
75     public:
76         RefBase*            refBase() const;
77 
78         void                incWeak(const void* id);
79         void                decWeak(const void* id);
80 
81         bool                attemptIncStrong(const void* id);
82 
83         //! This is only safe if you have set OBJECT_LIFETIME_FOREVER.
84         bool                attemptIncWeak(const void* id);
85 
86         //! DEBUGGING ONLY: Get current weak ref count.
87         int32_t             getWeakCount() const;
88 
89         //! DEBUGGING ONLY: Print references held on object.
90         void                printRefs() const;
91 
92         //! DEBUGGING ONLY: Enable tracking for this object.
93         // enable -- enable/disable tracking
94         // retain -- when tracking is enable, if true, then we save a stack trace
95         //           for each reference and dereference; when retain == false, we
96         //           match up references and dereferences and keep only the
97         //           outstanding ones.
98 
99         void                trackMe(bool enable, bool retain);
100     };
101 
102             weakref_type*   createWeak(const void* id) const;
103 
104             weakref_type*   getWeakRefs() const;
105 
106             //! DEBUGGING ONLY: Print references held on object.
printRefs()107     inline  void            printRefs() const { getWeakRefs()->printRefs(); }
108 
109             //! DEBUGGING ONLY: Enable tracking of object.
trackMe(bool enable,bool retain)110     inline  void            trackMe(bool enable, bool retain)
111     {
112         getWeakRefs()->trackMe(enable, retain);
113     }
114 
115     // used to override the RefBase destruction.
116     class Destroyer {
117         friend class RefBase;
118     public:
119         virtual ~Destroyer();
120     private:
121         virtual void destroy(RefBase const* base) = 0;
122     };
123 
124     // Make sure to never acquire a strong reference from this function. The
125     // same restrictions than for destructors apply.
126     void setDestroyer(Destroyer* destroyer);
127 
128 protected:
129                             RefBase();
130     virtual                 ~RefBase();
131 
132     //! Flags for extendObjectLifetime()
133     enum {
134         OBJECT_LIFETIME_WEAK    = 0x0001,
135         OBJECT_LIFETIME_FOREVER = 0x0003
136     };
137 
138             void            extendObjectLifetime(int32_t mode);
139 
140     //! Flags for onIncStrongAttempted()
141     enum {
142         FIRST_INC_STRONG = 0x0001
143     };
144 
145     virtual void            onFirstRef();
146     virtual void            onLastStrongRef(const void* id);
147     virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
148     virtual void            onLastWeakRef(const void* id);
149 
150 private:
151     friend class weakref_type;
152     class weakref_impl;
153 
154                             RefBase(const RefBase& o);
155             RefBase&        operator=(const RefBase& o);
156 
157         weakref_impl* const mRefs;
158 };
159 
160 // ---------------------------------------------------------------------------
161 
162 template <class T>
163 class LightRefBase
164 {
165 public:
LightRefBase()166     inline LightRefBase() : mCount(0) { }
incStrong(const void * id)167     inline void incStrong(const void* id) const {
168         android_atomic_inc(&mCount);
169     }
decStrong(const void * id)170     inline void decStrong(const void* id) const {
171         if (android_atomic_dec(&mCount) == 1) {
172             delete static_cast<const T*>(this);
173         }
174     }
175     //! DEBUGGING ONLY: Get current strong ref count.
getStrongCount()176     inline int32_t getStrongCount() const {
177         return mCount;
178     }
179 
180 protected:
~LightRefBase()181     inline ~LightRefBase() { }
182 
183 private:
184     mutable volatile int32_t mCount;
185 };
186 
187 // ---------------------------------------------------------------------------
188 
189 template <typename T>
190 class sp
191 {
192 public:
193     typedef typename RefBase::weakref_type weakref_type;
194 
sp()195     inline sp() : m_ptr(0) { }
196 
197     sp(T* other);
198     sp(const sp<T>& other);
199     template<typename U> sp(U* other);
200     template<typename U> sp(const sp<U>& other);
201 
202     ~sp();
203 
204     // Assignment
205 
206     sp& operator = (T* other);
207     sp& operator = (const sp<T>& other);
208 
209     template<typename U> sp& operator = (const sp<U>& other);
210     template<typename U> sp& operator = (U* other);
211 
212     //! Special optimization for use by ProcessState (and nobody else).
213     void force_set(T* other);
214 
215     // Reset
216 
217     void clear();
218 
219     // Accessors
220 
221     inline  T&      operator* () const  { return *m_ptr; }
222     inline  T*      operator-> () const { return m_ptr;  }
get()223     inline  T*      get() const         { return m_ptr; }
224 
225     // Operators
226 
227     COMPARE(==)
228     COMPARE(!=)
229     COMPARE(>)
230     COMPARE(<)
231     COMPARE(<=)
232     COMPARE(>=)
233 
234 private:
235     template<typename Y> friend class sp;
236     template<typename Y> friend class wp;
237 
238     // Optimization for wp::promote().
239     sp(T* p, weakref_type* refs);
240 
241     T*              m_ptr;
242 };
243 
244 template <typename T>
245 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
246 
247 // ---------------------------------------------------------------------------
248 
249 template <typename T>
250 class wp
251 {
252 public:
253     typedef typename RefBase::weakref_type weakref_type;
254 
wp()255     inline wp() : m_ptr(0) { }
256 
257     wp(T* other);
258     wp(const wp<T>& other);
259     wp(const sp<T>& other);
260     template<typename U> wp(U* other);
261     template<typename U> wp(const sp<U>& other);
262     template<typename U> wp(const wp<U>& other);
263 
264     ~wp();
265 
266     // Assignment
267 
268     wp& operator = (T* other);
269     wp& operator = (const wp<T>& other);
270     wp& operator = (const sp<T>& other);
271 
272     template<typename U> wp& operator = (U* other);
273     template<typename U> wp& operator = (const wp<U>& other);
274     template<typename U> wp& operator = (const sp<U>& other);
275 
276     void set_object_and_refs(T* other, weakref_type* refs);
277 
278     // promotion to sp
279 
280     sp<T> promote() const;
281 
282     // Reset
283 
284     void clear();
285 
286     // Accessors
287 
get_refs()288     inline  weakref_type* get_refs() const { return m_refs; }
289 
unsafe_get()290     inline  T* unsafe_get() const { return m_ptr; }
291 
292     // Operators
293 
294     COMPARE_WEAK(==)
295     COMPARE_WEAK(!=)
296     COMPARE_WEAK(>)
297     COMPARE_WEAK(<)
298     COMPARE_WEAK(<=)
299     COMPARE_WEAK(>=)
300 
301     inline bool operator == (const wp<T>& o) const {
302         return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
303     }
304     template<typename U>
305     inline bool operator == (const wp<U>& o) const {
306         return m_ptr == o.m_ptr;
307     }
308 
309     inline bool operator > (const wp<T>& o) const {
310         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
311     }
312     template<typename U>
313     inline bool operator > (const wp<U>& o) const {
314         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
315     }
316 
317     inline bool operator < (const wp<T>& o) const {
318         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
319     }
320     template<typename U>
321     inline bool operator < (const wp<U>& o) const {
322         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
323     }
324                          inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
325     template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
326                          inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
327     template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
328                          inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
329     template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
330 
331 private:
332     template<typename Y> friend class sp;
333     template<typename Y> friend class wp;
334 
335     T*              m_ptr;
336     weakref_type*   m_refs;
337 };
338 
339 template <typename T>
340 TextOutput& operator<<(TextOutput& to, const wp<T>& val);
341 
342 #undef COMPARE
343 #undef COMPARE_WEAK
344 
345 // ---------------------------------------------------------------------------
346 // No user serviceable parts below here.
347 
348 template<typename T>
sp(T * other)349 sp<T>::sp(T* other)
350     : m_ptr(other)
351 {
352     if (other) other->incStrong(this);
353 }
354 
355 template<typename T>
sp(const sp<T> & other)356 sp<T>::sp(const sp<T>& other)
357     : m_ptr(other.m_ptr)
358 {
359     if (m_ptr) m_ptr->incStrong(this);
360 }
361 
362 template<typename T> template<typename U>
sp(U * other)363 sp<T>::sp(U* other) : m_ptr(other)
364 {
365     if (other) other->incStrong(this);
366 }
367 
368 template<typename T> template<typename U>
sp(const sp<U> & other)369 sp<T>::sp(const sp<U>& other)
370     : m_ptr(other.m_ptr)
371 {
372     if (m_ptr) m_ptr->incStrong(this);
373 }
374 
375 template<typename T>
~sp()376 sp<T>::~sp()
377 {
378     if (m_ptr) m_ptr->decStrong(this);
379 }
380 
381 template<typename T>
382 sp<T>& sp<T>::operator = (const sp<T>& other) {
383     T* otherPtr(other.m_ptr);
384     if (otherPtr) otherPtr->incStrong(this);
385     if (m_ptr) m_ptr->decStrong(this);
386     m_ptr = otherPtr;
387     return *this;
388 }
389 
390 template<typename T>
391 sp<T>& sp<T>::operator = (T* other)
392 {
393     if (other) other->incStrong(this);
394     if (m_ptr) m_ptr->decStrong(this);
395     m_ptr = other;
396     return *this;
397 }
398 
399 template<typename T> template<typename U>
400 sp<T>& sp<T>::operator = (const sp<U>& other)
401 {
402     U* otherPtr(other.m_ptr);
403     if (otherPtr) otherPtr->incStrong(this);
404     if (m_ptr) m_ptr->decStrong(this);
405     m_ptr = otherPtr;
406     return *this;
407 }
408 
409 template<typename T> template<typename U>
410 sp<T>& sp<T>::operator = (U* other)
411 {
412     if (other) other->incStrong(this);
413     if (m_ptr) m_ptr->decStrong(this);
414     m_ptr = other;
415     return *this;
416 }
417 
418 template<typename T>
force_set(T * other)419 void sp<T>::force_set(T* other)
420 {
421     other->forceIncStrong(this);
422     m_ptr = other;
423 }
424 
425 template<typename T>
clear()426 void sp<T>::clear()
427 {
428     if (m_ptr) {
429         m_ptr->decStrong(this);
430         m_ptr = 0;
431     }
432 }
433 
434 template<typename T>
sp(T * p,weakref_type * refs)435 sp<T>::sp(T* p, weakref_type* refs)
436     : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
437 {
438 }
439 
440 template <typename T>
441 inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
442 {
443     to << "sp<>(" << val.get() << ")";
444     return to;
445 }
446 
447 // ---------------------------------------------------------------------------
448 
449 template<typename T>
wp(T * other)450 wp<T>::wp(T* other)
451     : m_ptr(other)
452 {
453     if (other) m_refs = other->createWeak(this);
454 }
455 
456 template<typename T>
wp(const wp<T> & other)457 wp<T>::wp(const wp<T>& other)
458     : m_ptr(other.m_ptr), m_refs(other.m_refs)
459 {
460     if (m_ptr) m_refs->incWeak(this);
461 }
462 
463 template<typename T>
wp(const sp<T> & other)464 wp<T>::wp(const sp<T>& other)
465     : m_ptr(other.m_ptr)
466 {
467     if (m_ptr) {
468         m_refs = m_ptr->createWeak(this);
469     }
470 }
471 
472 template<typename T> template<typename U>
wp(U * other)473 wp<T>::wp(U* other)
474     : m_ptr(other)
475 {
476     if (other) m_refs = other->createWeak(this);
477 }
478 
479 template<typename T> template<typename U>
wp(const wp<U> & other)480 wp<T>::wp(const wp<U>& other)
481     : m_ptr(other.m_ptr)
482 {
483     if (m_ptr) {
484         m_refs = other.m_refs;
485         m_refs->incWeak(this);
486     }
487 }
488 
489 template<typename T> template<typename U>
wp(const sp<U> & other)490 wp<T>::wp(const sp<U>& other)
491     : m_ptr(other.m_ptr)
492 {
493     if (m_ptr) {
494         m_refs = m_ptr->createWeak(this);
495     }
496 }
497 
498 template<typename T>
~wp()499 wp<T>::~wp()
500 {
501     if (m_ptr) m_refs->decWeak(this);
502 }
503 
504 template<typename T>
505 wp<T>& wp<T>::operator = (T* other)
506 {
507     weakref_type* newRefs =
508         other ? other->createWeak(this) : 0;
509     if (m_ptr) m_refs->decWeak(this);
510     m_ptr = other;
511     m_refs = newRefs;
512     return *this;
513 }
514 
515 template<typename T>
516 wp<T>& wp<T>::operator = (const wp<T>& other)
517 {
518     weakref_type* otherRefs(other.m_refs);
519     T* otherPtr(other.m_ptr);
520     if (otherPtr) otherRefs->incWeak(this);
521     if (m_ptr) m_refs->decWeak(this);
522     m_ptr = otherPtr;
523     m_refs = otherRefs;
524     return *this;
525 }
526 
527 template<typename T>
528 wp<T>& wp<T>::operator = (const sp<T>& other)
529 {
530     weakref_type* newRefs =
531         other != NULL ? other->createWeak(this) : 0;
532     T* otherPtr(other.m_ptr);
533     if (m_ptr) m_refs->decWeak(this);
534     m_ptr = otherPtr;
535     m_refs = newRefs;
536     return *this;
537 }
538 
539 template<typename T> template<typename U>
540 wp<T>& wp<T>::operator = (U* other)
541 {
542     weakref_type* newRefs =
543         other ? other->createWeak(this) : 0;
544     if (m_ptr) m_refs->decWeak(this);
545     m_ptr = other;
546     m_refs = newRefs;
547     return *this;
548 }
549 
550 template<typename T> template<typename U>
551 wp<T>& wp<T>::operator = (const wp<U>& other)
552 {
553     weakref_type* otherRefs(other.m_refs);
554     U* otherPtr(other.m_ptr);
555     if (otherPtr) otherRefs->incWeak(this);
556     if (m_ptr) m_refs->decWeak(this);
557     m_ptr = otherPtr;
558     m_refs = otherRefs;
559     return *this;
560 }
561 
562 template<typename T> template<typename U>
563 wp<T>& wp<T>::operator = (const sp<U>& other)
564 {
565     weakref_type* newRefs =
566         other != NULL ? other->createWeak(this) : 0;
567     U* otherPtr(other.m_ptr);
568     if (m_ptr) m_refs->decWeak(this);
569     m_ptr = otherPtr;
570     m_refs = newRefs;
571     return *this;
572 }
573 
574 template<typename T>
set_object_and_refs(T * other,weakref_type * refs)575 void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
576 {
577     if (other) refs->incWeak(this);
578     if (m_ptr) m_refs->decWeak(this);
579     m_ptr = other;
580     m_refs = refs;
581 }
582 
583 template<typename T>
promote()584 sp<T> wp<T>::promote() const
585 {
586     return sp<T>(m_ptr, m_refs);
587 }
588 
589 template<typename T>
clear()590 void wp<T>::clear()
591 {
592     if (m_ptr) {
593         m_refs->decWeak(this);
594         m_ptr = 0;
595     }
596 }
597 
598 template <typename T>
599 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
600 {
601     to << "wp<>(" << val.unsafe_get() << ")";
602     return to;
603 }
604 
605 }; // namespace android
606 
607 // ---------------------------------------------------------------------------
608 
609 #endif // ANDROID_REF_BASE_H
610