media/omx-plugin/include/ics/utils/RefBase.h

Thu, 22 Jan 2015 13:21:57 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Thu, 22 Jan 2015 13:21:57 +0100
branch
TOR_BUG_9701
changeset 15
b8a032363ba2
permissions
-rw-r--r--

Incorporate requested changes from Mozilla in review:
https://bugzilla.mozilla.org/show_bug.cgi?id=1123480#c6

     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  */
    17 #ifndef ANDROID_REF_BASE_H
    18 #define ANDROID_REF_BASE_H
    20 #include <cutils/atomic.h>
    22 #include <stdint.h>
    23 #include <sys/types.h>
    24 #include <stdlib.h>
    25 #include <string.h>
    27 #include <utils/StrongPointer.h>
    29 // ---------------------------------------------------------------------------
    30 namespace android {
    32 class TextOutput;
    33 TextOutput& printWeakPointer(TextOutput& to, const void* val);
    35 // ---------------------------------------------------------------------------
    37 #define COMPARE_WEAK(_op_)                                      \
    38 inline bool operator _op_ (const sp<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 U* o) const {                  \
    50     return m_ptr _op_ o;                                        \
    51 }
    53 // ---------------------------------------------------------------------------
    54 class ReferenceMover;
    55 class ReferenceConverterBase {
    56 public:
    57     virtual size_t getReferenceTypeSize() const = 0;
    58     virtual void* getReferenceBase(void const*) const = 0;
    59     inline virtual ~ReferenceConverterBase() { }
    60 };
    62 // ---------------------------------------------------------------------------
    64 class RefBase
    65 {
    66 public:
    67             void            incStrong(const void* id) const;
    68             void            decStrong(const void* id) const;
    70             void            forceIncStrong(const void* id) const;
    72             //! DEBUGGING ONLY: Get current strong ref count.
    73             int32_t         getStrongCount() const;
    75     class weakref_type
    76     {
    77     public:
    78         RefBase*            refBase() const;
    80         void                incWeak(const void* id);
    81         void                decWeak(const void* id);
    83         // acquires a strong reference if there is already one.
    84         bool                attemptIncStrong(const void* id);
    86         // acquires a weak reference if there is already one.
    87         // This is not always safe. see ProcessState.cpp and BpBinder.cpp
    88         // for proper use.
    89         bool                attemptIncWeak(const void* id);
    91         //! DEBUGGING ONLY: Get current weak ref count.
    92         int32_t             getWeakCount() const;
    94         //! DEBUGGING ONLY: Print references held on object.
    95         void                printRefs() const;
    97         //! DEBUGGING ONLY: Enable tracking for this object.
    98         // enable -- enable/disable tracking
    99         // retain -- when tracking is enable, if true, then we save a stack trace
   100         //           for each reference and dereference; when retain == false, we
   101         //           match up references and dereferences and keep only the 
   102         //           outstanding ones.
   104         void                trackMe(bool enable, bool retain);
   105     };
   107             weakref_type*   createWeak(const void* id) const;
   109             weakref_type*   getWeakRefs() const;
   111             //! DEBUGGING ONLY: Print references held on object.
   112     inline  void            printRefs() const { getWeakRefs()->printRefs(); }
   114             //! DEBUGGING ONLY: Enable tracking of object.
   115     inline  void            trackMe(bool enable, bool retain)
   116     { 
   117         getWeakRefs()->trackMe(enable, retain); 
   118     }
   120     typedef RefBase basetype;
   122 protected:
   123                             RefBase();
   124     virtual                 ~RefBase();
   126     //! Flags for extendObjectLifetime()
   127     enum {
   128         OBJECT_LIFETIME_STRONG  = 0x0000,
   129         OBJECT_LIFETIME_WEAK    = 0x0001,
   130         OBJECT_LIFETIME_MASK    = 0x0001
   131     };
   133             void            extendObjectLifetime(int32_t mode);
   135     //! Flags for onIncStrongAttempted()
   136     enum {
   137         FIRST_INC_STRONG = 0x0001
   138     };
   140     virtual void            onFirstRef();
   141     virtual void            onLastStrongRef(const void* id);
   142     virtual bool            onIncStrongAttempted(uint32_t flags, const void* id);
   143     virtual void            onLastWeakRef(const void* id);
   145 private:
   146     friend class ReferenceMover;
   147     static void moveReferences(void* d, void const* s, size_t n,
   148             const ReferenceConverterBase& caster);
   150 private:
   151     friend class weakref_type;
   152     class weakref_impl;
   154                             RefBase(const RefBase& o);
   155             RefBase&        operator=(const RefBase& o);
   157         weakref_impl* const mRefs;
   158 };
   160 // ---------------------------------------------------------------------------
   162 template <class T>
   163 class LightRefBase
   164 {
   165 public:
   166     inline LightRefBase() : mCount(0) { }
   167     inline void incStrong(const void* id) const {
   168         android_atomic_inc(&mCount);
   169     }
   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.
   176     inline int32_t getStrongCount() const {
   177         return mCount;
   178     }
   180     typedef LightRefBase<T> basetype;
   182 protected:
   183     inline ~LightRefBase() { }
   185 private:
   186     friend class ReferenceMover;
   187     inline static void moveReferences(void* d, void const* s, size_t n,
   188             const ReferenceConverterBase& caster) { }
   190 private:
   191     mutable volatile int32_t mCount;
   192 };
   194 // ---------------------------------------------------------------------------
   196 template <typename T>
   197 class wp
   198 {
   199 public:
   200     typedef typename RefBase::weakref_type weakref_type;
   202     inline wp() : m_ptr(0) { }
   204     wp(T* other);
   205     wp(const wp<T>& other);
   206     wp(const sp<T>& other);
   207     template<typename U> wp(U* other);
   208     template<typename U> wp(const sp<U>& other);
   209     template<typename U> wp(const wp<U>& other);
   211     ~wp();
   213     // Assignment
   215     wp& operator = (T* other);
   216     wp& operator = (const wp<T>& other);
   217     wp& operator = (const sp<T>& other);
   219     template<typename U> wp& operator = (U* other);
   220     template<typename U> wp& operator = (const wp<U>& other);
   221     template<typename U> wp& operator = (const sp<U>& other);
   223     void set_object_and_refs(T* other, weakref_type* refs);
   225     // promotion to sp
   227     sp<T> promote() const;
   229     // Reset
   231     void clear();
   233     // Accessors
   235     inline  weakref_type* get_refs() const { return m_refs; }
   237     inline  T* unsafe_get() const { return m_ptr; }
   239     // Operators
   241     COMPARE_WEAK(==)
   242     COMPARE_WEAK(!=)
   243     COMPARE_WEAK(>)
   244     COMPARE_WEAK(<)
   245     COMPARE_WEAK(<=)
   246     COMPARE_WEAK(>=)
   248     inline bool operator == (const wp<T>& o) const {
   249         return (m_ptr == o.m_ptr) && (m_refs == o.m_refs);
   250     }
   251     template<typename U>
   252     inline bool operator == (const wp<U>& o) const {
   253         return m_ptr == o.m_ptr;
   254     }
   256     inline bool operator > (const wp<T>& o) const {
   257         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
   258     }
   259     template<typename U>
   260     inline bool operator > (const wp<U>& o) const {
   261         return (m_ptr == o.m_ptr) ? (m_refs > o.m_refs) : (m_ptr > o.m_ptr);
   262     }
   264     inline bool operator < (const wp<T>& o) const {
   265         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
   266     }
   267     template<typename U>
   268     inline bool operator < (const wp<U>& o) const {
   269         return (m_ptr == o.m_ptr) ? (m_refs < o.m_refs) : (m_ptr < o.m_ptr);
   270     }
   271                          inline bool operator != (const wp<T>& o) const { return m_refs != o.m_refs; }
   272     template<typename U> inline bool operator != (const wp<U>& o) const { return !operator == (o); }
   273                          inline bool operator <= (const wp<T>& o) const { return !operator > (o); }
   274     template<typename U> inline bool operator <= (const wp<U>& o) const { return !operator > (o); }
   275                          inline bool operator >= (const wp<T>& o) const { return !operator < (o); }
   276     template<typename U> inline bool operator >= (const wp<U>& o) const { return !operator < (o); }
   278 private:
   279     template<typename Y> friend class sp;
   280     template<typename Y> friend class wp;
   282     T*              m_ptr;
   283     weakref_type*   m_refs;
   284 };
   286 template <typename T>
   287 TextOutput& operator<<(TextOutput& to, const wp<T>& val);
   289 #undef COMPARE_WEAK
   291 // ---------------------------------------------------------------------------
   292 // No user serviceable parts below here.
   294 template<typename T>
   295 wp<T>::wp(T* other)
   296     : m_ptr(other)
   297 {
   298     if (other) m_refs = other->createWeak(this);
   299 }
   301 template<typename T>
   302 wp<T>::wp(const wp<T>& other)
   303     : m_ptr(other.m_ptr), m_refs(other.m_refs)
   304 {
   305     if (m_ptr) m_refs->incWeak(this);
   306 }
   308 template<typename T>
   309 wp<T>::wp(const sp<T>& other)
   310     : m_ptr(other.m_ptr)
   311 {
   312     if (m_ptr) {
   313         m_refs = m_ptr->createWeak(this);
   314     }
   315 }
   317 template<typename T> template<typename U>
   318 wp<T>::wp(U* other)
   319     : m_ptr(other)
   320 {
   321     if (other) m_refs = other->createWeak(this);
   322 }
   324 template<typename T> template<typename U>
   325 wp<T>::wp(const wp<U>& other)
   326     : m_ptr(other.m_ptr)
   327 {
   328     if (m_ptr) {
   329         m_refs = other.m_refs;
   330         m_refs->incWeak(this);
   331     }
   332 }
   334 template<typename T> template<typename U>
   335 wp<T>::wp(const sp<U>& other)
   336     : m_ptr(other.m_ptr)
   337 {
   338     if (m_ptr) {
   339         m_refs = m_ptr->createWeak(this);
   340     }
   341 }
   343 template<typename T>
   344 wp<T>::~wp()
   345 {
   346     if (m_ptr) m_refs->decWeak(this);
   347 }
   349 template<typename T>
   350 wp<T>& wp<T>::operator = (T* other)
   351 {
   352     weakref_type* newRefs =
   353         other ? other->createWeak(this) : 0;
   354     if (m_ptr) m_refs->decWeak(this);
   355     m_ptr = other;
   356     m_refs = newRefs;
   357     return *this;
   358 }
   360 template<typename T>
   361 wp<T>& wp<T>::operator = (const wp<T>& other)
   362 {
   363     weakref_type* otherRefs(other.m_refs);
   364     T* otherPtr(other.m_ptr);
   365     if (otherPtr) otherRefs->incWeak(this);
   366     if (m_ptr) m_refs->decWeak(this);
   367     m_ptr = otherPtr;
   368     m_refs = otherRefs;
   369     return *this;
   370 }
   372 template<typename T>
   373 wp<T>& wp<T>::operator = (const sp<T>& other)
   374 {
   375     weakref_type* newRefs =
   376         other != NULL ? other->createWeak(this) : 0;
   377     T* otherPtr(other.m_ptr);
   378     if (m_ptr) m_refs->decWeak(this);
   379     m_ptr = otherPtr;
   380     m_refs = newRefs;
   381     return *this;
   382 }
   384 template<typename T> template<typename U>
   385 wp<T>& wp<T>::operator = (U* other)
   386 {
   387     weakref_type* newRefs =
   388         other ? other->createWeak(this) : 0;
   389     if (m_ptr) m_refs->decWeak(this);
   390     m_ptr = other;
   391     m_refs = newRefs;
   392     return *this;
   393 }
   395 template<typename T> template<typename U>
   396 wp<T>& wp<T>::operator = (const wp<U>& other)
   397 {
   398     weakref_type* otherRefs(other.m_refs);
   399     U* otherPtr(other.m_ptr);
   400     if (otherPtr) otherRefs->incWeak(this);
   401     if (m_ptr) m_refs->decWeak(this);
   402     m_ptr = otherPtr;
   403     m_refs = otherRefs;
   404     return *this;
   405 }
   407 template<typename T> template<typename U>
   408 wp<T>& wp<T>::operator = (const sp<U>& other)
   409 {
   410     weakref_type* newRefs =
   411         other != NULL ? other->createWeak(this) : 0;
   412     U* otherPtr(other.m_ptr);
   413     if (m_ptr) m_refs->decWeak(this);
   414     m_ptr = otherPtr;
   415     m_refs = newRefs;
   416     return *this;
   417 }
   419 template<typename T>
   420 void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
   421 {
   422     if (other) refs->incWeak(this);
   423     if (m_ptr) m_refs->decWeak(this);
   424     m_ptr = other;
   425     m_refs = refs;
   426 }
   428 template<typename T>
   429 sp<T> wp<T>::promote() const
   430 {
   431     sp<T> result;
   432     if (m_ptr && m_refs->attemptIncStrong(&result)) {
   433         result.set_pointer(m_ptr);
   434     }
   435     return result;
   436 }
   438 template<typename T>
   439 void wp<T>::clear()
   440 {
   441     if (m_ptr) {
   442         m_refs->decWeak(this);
   443         m_ptr = 0;
   444     }
   445 }
   447 template <typename T>
   448 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
   449 {
   450     return printWeakPointer(to, val.unsafe_get());
   451 }
   453 // ---------------------------------------------------------------------------
   455 // this class just serves as a namespace so TYPE::moveReferences can stay
   456 // private.
   458 class ReferenceMover {
   459     // StrongReferenceCast and WeakReferenceCast do the impedance matching
   460     // between the generic (void*) implementation in Refbase and the strongly typed
   461     // template specializations below.
   463     template <typename TYPE>
   464     struct StrongReferenceCast : public ReferenceConverterBase {
   465         virtual size_t getReferenceTypeSize() const { return sizeof( sp<TYPE> ); }
   466         virtual void* getReferenceBase(void const* p) const {
   467             sp<TYPE> const* sptr(reinterpret_cast<sp<TYPE> const*>(p));
   468             return static_cast<typename TYPE::basetype *>(sptr->get());
   469         }
   470     };
   472     template <typename TYPE>
   473     struct WeakReferenceCast : public ReferenceConverterBase {
   474         virtual size_t getReferenceTypeSize() const { return sizeof( wp<TYPE> ); }
   475         virtual void* getReferenceBase(void const* p) const {
   476             wp<TYPE> const* sptr(reinterpret_cast<wp<TYPE> const*>(p));
   477             return static_cast<typename TYPE::basetype *>(sptr->unsafe_get());
   478         }
   479     };
   481 public:
   482     template<typename TYPE> static inline
   483     void move_references(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
   484         memmove(d, s, n*sizeof(sp<TYPE>));
   485         StrongReferenceCast<TYPE> caster;
   486         TYPE::moveReferences(d, s, n, caster);
   487     }
   488     template<typename TYPE> static inline
   489     void move_references(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
   490         memmove(d, s, n*sizeof(wp<TYPE>));
   491         WeakReferenceCast<TYPE> caster;
   492         TYPE::moveReferences(d, s, n, caster);
   493     }
   494 };
   496 // specialization for moving sp<> and wp<> types.
   497 // these are used by the [Sorted|Keyed]Vector<> implementations
   498 // sp<> and wp<> need to be handled specially, because they do not
   499 // have trivial copy operation in the general case (see RefBase.cpp
   500 // when DEBUG ops are enabled), but can be implemented very
   501 // efficiently in most cases.
   503 template<typename TYPE> inline
   504 void move_forward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
   505     ReferenceMover::move_references(d, s, n);
   506 }
   508 template<typename TYPE> inline
   509 void move_backward_type(sp<TYPE>* d, sp<TYPE> const* s, size_t n) {
   510     ReferenceMover::move_references(d, s, n);
   511 }
   513 template<typename TYPE> inline
   514 void move_forward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
   515     ReferenceMover::move_references(d, s, n);
   516 }
   518 template<typename TYPE> inline
   519 void move_backward_type(wp<TYPE>* d, wp<TYPE> const* s, size_t n) {
   520     ReferenceMover::move_references(d, s, n);
   521 }
   524 }; // namespace android
   526 // ---------------------------------------------------------------------------
   528 #endif // ANDROID_REF_BASE_H

mercurial