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