LCOV - code coverage report
Current view: top level - media/libstagefright/system/core/include/utils - RefBase.h (source / functions) Hit Total Coverage
Test: output.info Lines: 0 1 0.0 %
Date: 2017-07-14 16:53:18 Functions: 0 1 0.0 %
Legend: Lines: hit not hit

          Line data    Source code
       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             : 
      22             : #include <stdint.h>
      23             : #include <sys/types.h>
      24             : #include <stdlib.h>
      25             : #include <string.h>
      26             : 
      27             : #include <utils/StrongPointer.h>
      28             : #include <utils/TypeHelpers.h>
      29             : 
      30             : #ifdef _MSC_VER
      31             : #define __attribute__(X)
      32             : #endif
      33             : 
      34             : // ---------------------------------------------------------------------------
      35             : namespace stagefright {
      36             : 
      37             : class TextOutput;
      38             : TextOutput& printWeakPointer(TextOutput& to, const void* val);
      39             : 
      40             : // ---------------------------------------------------------------------------
      41             : 
      42             : #define COMPARE_WEAK(_op_)                                      \
      43             : inline bool operator _op_ (const sp<T>& o) const {              \
      44             :     return m_ptr _op_ o.m_ptr;                                  \
      45             : }                                                               \
      46             : inline bool operator _op_ (const T* o) const {                  \
      47             :     return m_ptr _op_ o;                                        \
      48             : }                                                               \
      49             : template<typename U>                                            \
      50             : inline bool operator _op_ (const sp<U>& o) const {              \
      51             :     return m_ptr _op_ o.m_ptr;                                  \
      52             : }                                                               \
      53             : template<typename U>                                            \
      54             : inline bool operator _op_ (const U* o) const {                  \
      55             :     return m_ptr _op_ o;                                        \
      56             : }
      57             : 
      58             : // ---------------------------------------------------------------------------
      59             : 
      60             : class ReferenceRenamer {
      61             : protected:
      62             :     // destructor is purposedly not virtual so we avoid code overhead from
      63             :     // subclasses; we have to make it protected to guarantee that it
      64             :     // cannot be called from this base class (and to make strict compilers
      65             :     // happy).
      66             :     ~ReferenceRenamer() { }
      67             : public:
      68             :     virtual void operator()(size_t i) const = 0;
      69             : };
      70             : 
      71             : // ---------------------------------------------------------------------------
      72             : 
      73             : class RefBase
      74             : {
      75             : public:
      76             :             void            incStrong(const void* id) const;
      77             :             void            decStrong(const void* id) const;
      78             :     
      79             :             void            forceIncStrong(const void* id) const;
      80             : 
      81             :             //! DEBUGGING ONLY: Get current strong ref count.
      82             :             int32_t         getStrongCount() const;
      83             : 
      84           0 :     class weakref_type
      85             :     {
      86             :     public:
      87             :         RefBase*            refBase() const;
      88             :         
      89             :         void                incWeak(const void* id);
      90             :         void                decWeak(const void* id);
      91             :         
      92             :         // acquires a strong reference if there is already one.
      93             :         bool                attemptIncStrong(const void* id);
      94             :         
      95             :         // acquires a weak reference if there is already one.
      96             :         // This is not always safe. see ProcessState.cpp and BpBinder.cpp
      97             :         // for proper use.
      98             :         bool                attemptIncWeak(const void* id);
      99             : 
     100             :         //! DEBUGGING ONLY: Get current weak ref count.
     101             :         int32_t             getWeakCount() const;
     102             : 
     103             :         //! DEBUGGING ONLY: Print references held on object.
     104             :         void                printRefs() const;
     105             : 
     106             :         //! DEBUGGING ONLY: Enable tracking for this object.
     107             :         // enable -- enable/disable tracking
     108             :         // retain -- when tracking is enable, if true, then we save a stack trace
     109             :         //           for each reference and dereference; when retain == false, we
     110             :         //           match up references and dereferences and keep only the 
     111             :         //           outstanding ones.
     112             :         
     113             :         void                trackMe(bool enable, bool retain);
     114             :     };
     115             :     
     116             :             weakref_type*   createWeak(const void* id) const;
     117             :             
     118             :             weakref_type*   getWeakRefs() const;
     119             : 
     120             :             //! DEBUGGING ONLY: Print references held on object.
     121             :     inline  void            printRefs() const { getWeakRefs()->printRefs(); }
     122             : 
     123             :             //! DEBUGGING ONLY: Enable tracking of object.
     124             :     inline  void            trackMe(bool enable, bool retain)
     125             :     { 
     126             :         getWeakRefs()->trackMe(enable, retain); 
     127             :     }
     128             : 
     129             :     typedef RefBase basetype;
     130             : 
     131             : protected:
     132             :                             RefBase();
     133             :     virtual                 ~RefBase();
     134             :     
     135             :     //! Flags for extendObjectLifetime()
     136             :     enum {
     137             :         OBJECT_LIFETIME_STRONG  = 0x0000,
     138             :         OBJECT_LIFETIME_WEAK    = 0x0001,
     139             :         OBJECT_LIFETIME_MASK    = 0x0001
     140             :     };
     141             :     
     142             :             void            extendObjectLifetime(int32_t mode);
     143             :             
     144             :     //! Flags for onIncStrongAttempted()
     145             :     enum {
     146             :         FIRST_INC_STRONG = 0x0001
     147             :     };
     148             :     
     149             :     virtual void            onFirstRef();
     150             :     virtual void            onLastStrongRef(const void* id);
     151             :     virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
     152             :     virtual void            onLastWeakRef(const void* id);
     153             : 
     154             : private:
     155             :     friend class weakref_type;
     156             :     class weakref_impl;
     157             :     
     158             :                             RefBase(const RefBase& o);
     159             :             RefBase&        operator=(const RefBase& o);
     160             : 
     161             : private:
     162             :     friend class ReferenceMover;
     163             : 
     164             :     static void renameRefs(size_t n, const ReferenceRenamer& renamer);
     165             : 
     166             :     static void renameRefId(weakref_type* ref,
     167             :             const void* old_id, const void* new_id);
     168             : 
     169             :     static void renameRefId(RefBase* ref,
     170             :             const void* old_id, const void* new_id);
     171             : 
     172             :         weakref_impl* const mRefs;
     173             : };
     174             : 
     175             : // ---------------------------------------------------------------------------
     176             : 
     177             : template <class T>
     178             : class LightRefBase
     179             : {
     180             : public:
     181             :     inline LightRefBase() : mCount(0) { }
     182             :     inline void incStrong(__attribute__((unused)) const void* id) const {
     183             :         android_atomic_inc(&mCount);
     184             :     }
     185             :     inline void decStrong(__attribute__((unused)) const void* id) const {
     186             :         if (android_atomic_dec(&mCount) == 1) {
     187             :             delete static_cast<const T*>(this);
     188             :         }
     189             :     }
     190             :     //! DEBUGGING ONLY: Get current strong ref count.
     191             :     inline int32_t getStrongCount() const {
     192             :         return mCount;
     193             :     }
     194             : 
     195             :     typedef LightRefBase<T> basetype;
     196             : 
     197             : protected:
     198             :     inline ~LightRefBase() { }
     199             : 
     200             : private:
     201             :     friend class ReferenceMover;
     202             :     inline static void renameRefs(size_t n, const ReferenceRenamer& renamer) { }
     203             :     inline static void renameRefId(T* ref,
     204             :             const void* old_id, const void* new_id) { }
     205             : 
     206             : private:
     207             :     mutable volatile int32_t mCount;
     208             : };
     209             : 
     210             : // ---------------------------------------------------------------------------
     211             : 
     212             : template <typename T>
     213             : class wp
     214             : {
     215             : public:
     216             :     typedef typename RefBase::weakref_type weakref_type;
     217             :     
     218             :     inline wp() : m_ptr(0) { }
     219             : 
     220             :     wp(T* other);
     221             :     wp(const wp<T>& other);
     222             :     wp(const sp<T>& other);
     223             :     template<typename U> wp(U* other);
     224             :     template<typename U> wp(const sp<U>& other);
     225             :     template<typename U> wp(const wp<U>& other);
     226             : 
     227             :     ~wp();
     228             :     
     229             :     // Assignment
     230             : 
     231             :     wp& operator = (T* other);
     232             :     wp& operator = (const wp<T>& other);
     233             :     wp& operator = (const sp<T>& other);
     234             :     
     235             :     template<typename U> wp& operator = (U* other);
     236             :     template<typename U> wp& operator = (const wp<U>& other);
     237             :     template<typename U> wp& operator = (const sp<U>& other);
     238             :     
     239             :     void set_object_and_refs(T* other, weakref_type* refs);
     240             : 
     241             :     // promotion to sp
     242             :     
     243             :     sp<T> promote() const;
     244             : 
     245             :     // Reset
     246             :     
     247             :     void clear();
     248             : 
     249             :     // Accessors
     250             :     
     251             :     inline  weakref_type* get_refs() const { return m_refs; }
     252             :     
     253             :     inline  T* unsafe_get() const { return m_ptr; }
     254             : 
     255             :     // Operators
     256             : 
     257             :     COMPARE_WEAK(==)
     258             :     COMPARE_WEAK(!=)
     259             :     COMPARE_WEAK(>)
     260             :     COMPARE_WEAK(<)
     261             :     COMPARE_WEAK(<=)
     262             :     COMPARE_WEAK(>=)
     263             : 
     264             :     inline bool operator == (const wp<T>& o) const {
     265             :         return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
     266             :     }
     267             :     template<typename U>
     268             :     inline bool operator == (const wp<U>& o) const {
     269             :         return m_ptr == o.m_ptr;
     270             :     }
     271             : 
     272             :     inline bool operator > (const wp<T>& o) const {
     273             :         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
     274             :     }
     275             :     template<typename U>
     276             :     inline bool operator > (const wp<U>& o) const {
     277             :         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
     278             :     }
     279             : 
     280             :     inline bool operator < (const wp<T>& o) const {
     281             :         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
     282             :     }
     283             :     template<typename U>
     284             :     inline bool operator < (const wp<U>& o) const {
     285             :         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
     286             :     }
     287             :                          inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
     288             :     template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
     289             :                          inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
     290             :     template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
     291             :                          inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
     292             :     template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
     293             : 
     294             : private:
     295             :     template<typename Y> friend class sp;
     296             :     template<typename Y> friend class wp;
     297             : 
     298             :     T*              m_ptr;
     299             :     weakref_type*   m_refs;
     300             : };
     301             : 
     302             : template <typename T>
     303             : TextOutput& operator<<(TextOutput& to, const wp<T>& val);
     304             : 
     305             : #undef COMPARE_WEAK
     306             : 
     307             : // ---------------------------------------------------------------------------
     308             : // No user serviceable parts below here.
     309             : 
     310             : template<typename T>
     311             : wp<T>::wp(T* other)
     312             :     : m_ptr(other)
     313             : {
     314             :     if (other) m_refs = other->createWeak(this);
     315             : }
     316             : 
     317             : template<typename T>
     318             : wp<T>::wp(const wp<T>& other)
     319             :     : m_ptr(other.m_ptr), m_refs(other.m_refs)
     320             : {
     321             :     if (m_ptr) m_refs->incWeak(this);
     322             : }
     323             : 
     324             : template<typename T>
     325             : wp<T>::wp(const sp<T>& other)
     326             :     : m_ptr(other.m_ptr)
     327             : {
     328             :     if (m_ptr) {
     329             :         m_refs = m_ptr->createWeak(this);
     330             :     }
     331             : }
     332             : 
     333             : template<typename T> template<typename U>
     334             : wp<T>::wp(U* other)
     335             :     : m_ptr(other)
     336             : {
     337             :     if (other) m_refs = other->createWeak(this);
     338             : }
     339             : 
     340             : template<typename T> template<typename U>
     341             : wp<T>::wp(const wp<U>& other)
     342             :     : m_ptr(other.m_ptr)
     343             : {
     344             :     if (m_ptr) {
     345             :         m_refs = other.m_refs;
     346             :         m_refs->incWeak(this);
     347             :     }
     348             : }
     349             : 
     350             : template<typename T> template<typename U>
     351             : wp<T>::wp(const sp<U>& other)
     352             :     : m_ptr(other.m_ptr)
     353             : {
     354             :     if (m_ptr) {
     355             :         m_refs = m_ptr->createWeak(this);
     356             :     }
     357             : }
     358             : 
     359             : template<typename T>
     360             : wp<T>::~wp()
     361             : {
     362             :     if (m_ptr) m_refs->decWeak(this);
     363             : }
     364             : 
     365             : template<typename T>
     366             : wp<T>& wp<T>::operator = (T* other)
     367             : {
     368             :     weakref_type* newRefs =
     369             :         other ? other->createWeak(this) : 0;
     370             :     if (m_ptr) m_refs->decWeak(this);
     371             :     m_ptr = other;
     372             :     m_refs = newRefs;
     373             :     return *this;
     374             : }
     375             : 
     376             : template<typename T>
     377             : wp<T>& wp<T>::operator = (const wp<T>& other)
     378             : {
     379             :     weakref_type* otherRefs(other.m_refs);
     380             :     T* otherPtr(other.m_ptr);
     381             :     if (otherPtr) otherRefs->incWeak(this);
     382             :     if (m_ptr) m_refs->decWeak(this);
     383             :     m_ptr = otherPtr;
     384             :     m_refs = otherRefs;
     385             :     return *this;
     386             : }
     387             : 
     388             : template<typename T>
     389             : wp<T>& wp<T>::operator = (const sp<T>& other)
     390             : {
     391             :     weakref_type* newRefs =
     392             :         other != NULL ? other->createWeak(this) : 0;
     393             :     T* otherPtr(other.m_ptr);
     394             :     if (m_ptr) m_refs->decWeak(this);
     395             :     m_ptr = otherPtr;
     396             :     m_refs = newRefs;
     397             :     return *this;
     398             : }
     399             : 
     400             : template<typename T> template<typename U>
     401             : wp<T>& wp<T>::operator = (U* other)
     402             : {
     403             :     weakref_type* newRefs =
     404             :         other ? other->createWeak(this) : 0;
     405             :     if (m_ptr) m_refs->decWeak(this);
     406             :     m_ptr = other;
     407             :     m_refs = newRefs;
     408             :     return *this;
     409             : }
     410             : 
     411             : template<typename T> template<typename U>
     412             : wp<T>& wp<T>::operator = (const wp<U>& other)
     413             : {
     414             :     weakref_type* otherRefs(other.m_refs);
     415             :     U* otherPtr(other.m_ptr);
     416             :     if (otherPtr) otherRefs->incWeak(this);
     417             :     if (m_ptr) m_refs->decWeak(this);
     418             :     m_ptr = otherPtr;
     419             :     m_refs = otherRefs;
     420             :     return *this;
     421             : }
     422             : 
     423             : template<typename T> template<typename U>
     424             : wp<T>& wp<T>::operator = (const sp<U>& other)
     425             : {
     426             :     weakref_type* newRefs =
     427             :         other != NULL ? other->createWeak(this) : 0;
     428             :     U* otherPtr(other.m_ptr);
     429             :     if (m_ptr) m_refs->decWeak(this);
     430             :     m_ptr = otherPtr;
     431             :     m_refs = newRefs;
     432             :     return *this;
     433             : }
     434             : 
     435             : template<typename T>
     436             : void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
     437             : {
     438             :     if (other) refs->incWeak(this);
     439             :     if (m_ptr) m_refs->decWeak(this);
     440             :     m_ptr = other;
     441             :     m_refs = refs;
     442             : }
     443             : 
     444             : template<typename T>
     445             : sp<T> wp<T>::promote() const
     446             : {
     447             :     sp<T> result;
     448             :     if (m_ptr && m_refs->attemptIncStrong(&result)) {
     449             :         result.set_pointer(m_ptr);
     450             :     }
     451             :     return result;
     452             : }
     453             : 
     454             : template<typename T>
     455             : void wp<T>::clear()
     456             : {
     457             :     if (m_ptr) {
     458             :         m_refs->decWeak(this);
     459             :         m_ptr = 0;
     460             :     }
     461             : }
     462             : 
     463             : template <typename T>
     464             : inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
     465             : {
     466             :     return printWeakPointer(to, val.unsafe_get());
     467             : }
     468             : 
     469             : // ---------------------------------------------------------------------------
     470             : 
     471             : // this class just serves as a namespace so TYPE::moveReferences can stay
     472             : // private.
     473             : class ReferenceMover {
     474             : public:
     475             :     // it would be nice if we could make sure no extra code is generated
     476             :     // for sp<TYPE> or wp<TYPE> when TYPE is a descendant of RefBase:
     477             :     // Using a sp<RefBase> override doesn't work; it's a bit like we wanted
     478             :     // a template<typename TYPE inherits RefBase> template...
     479             : 
     480             :     template<typename TYPE> static inline
     481             :     void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
     482             : 
     483             :         class Renamer : public ReferenceRenamer {
     484             :             sp<TYPE>* d;
     485             :             sp<TYPE> const* s;
     486             :             virtual void operator()(size_t i) const {
     487             :                 // The id are known to be the sp<>'s this pointer
     488             :                 TYPE::renameRefId(d[i].get(), &s[i], &d[i]);
     489             :             }
     490             :         public:
     491             :             Renamer(sp<TYPE>* d, sp<TYPE> const* s) : s(s), d(d) { }
     492             :         };
     493             : 
     494             :         memmove(d, s, n*sizeof(sp<TYPE>));
     495             :         TYPE::renameRefs(n, Renamer(d, s));
     496             :     }
     497             : 
     498             : 
     499             :     template<typename TYPE> static inline
     500             :     void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
     501             : 
     502             :         class Renamer : public ReferenceRenamer {
     503             :             wp<TYPE>* d;
     504             :             wp<TYPE> const* s;
     505             :             virtual void operator()(size_t i) const {
     506             :                 // The id are known to be the wp<>'s this pointer
     507             :                 TYPE::renameRefId(d[i].get_refs(), &s[i], &d[i]);
     508             :             }
     509             :         public:
     510             :             Renamer(wp<TYPE>* d, wp<TYPE> const* s) : s(s), d(d) { }
     511             :         };
     512             : 
     513             :         memmove(d, s, n*sizeof(wp<TYPE>));
     514             :         TYPE::renameRefs(n, Renamer(d, s));
     515             :     }
     516             : };
     517             : 
     518             : // specialization for moving sp<> and wp<> types.
     519             : // these are used by the [Sorted|Keyed]Vector<> implementations
     520             : // sp<> and wp<> need to be handled specially, because they do not
     521             : // have trivial copy operation in the general case (see RefBase.cpp
     522             : // when DEBUG ops are enabled), but can be implemented very
     523             : // efficiently in most cases.
     524             : 
     525             : template<typename TYPE> inline
     526             : void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
     527             :     ReferenceMover::move_references(d, s, n);
     528             : }
     529             : 
     530             : template<typename TYPE> inline
     531             : void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
     532             :     ReferenceMover::move_references(d, s, n);
     533             : }
     534             : 
     535             : template<typename TYPE> inline
     536             : void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
     537             :     ReferenceMover::move_references(d, s, n);
     538             : }
     539             : 
     540             : template<typename TYPE> inline
     541             : void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
     542             :     ReferenceMover::move_references(d, s, n);
     543             : }
     544             : 
     545             : 
     546             : }; // namespace stagefright
     547             : 
     548             : #ifdef _MSC_VER
     549             : #undef __attribute__
     550             : #endif
     551             : 
     552             : // ---------------------------------------------------------------------------
     553             : 
     554             : #endif // ANDROID_REF_BASE_H

Generated by: LCOV version 1.13