media/omx-plugin/include/gb/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>
    21 #include <utils/TextOutput.h>
    23 #include <stdint.h>
    24 #include <sys/types.h>
    25 #include <stdlib.h>
    27 // ---------------------------------------------------------------------------
    28 namespace android {
    30 template<typename T> class wp;
    32 // ---------------------------------------------------------------------------
    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 }
    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 }
    60 // ---------------------------------------------------------------------------
    62 class RefBase
    63 {
    64 public:
    65             void            incStrong(const void* id) const;
    66             void            decStrong(const void* id) const;
    68             void            forceIncStrong(const void* id) const;
    70             //! DEBUGGING ONLY: Get current strong ref count.
    71             int32_t         getStrongCount() const;
    73     class weakref_type
    74     {
    75     public:
    76         RefBase*            refBase() const;
    78         void                incWeak(const void* id);
    79         void                decWeak(const void* id);
    81         bool                attemptIncStrong(const void* id);
    83         //! This is only safe if you have set OBJECT_LIFETIME_FOREVER.
    84         bool                attemptIncWeak(const void* id);
    86         //! DEBUGGING ONLY: Get current weak ref count.
    87         int32_t             getWeakCount() const;
    89         //! DEBUGGING ONLY: Print references held on object.
    90         void                printRefs() const;
    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.
    99         void                trackMe(bool enable, bool retain);
   100     };
   102             weakref_type*   createWeak(const void* id) const;
   104             weakref_type*   getWeakRefs() const;
   106             //! DEBUGGING ONLY: Print references held on object.
   107     inline  void            printRefs() const { getWeakRefs()->printRefs(); }
   109             //! DEBUGGING ONLY: Enable tracking of object.
   110     inline  void            trackMe(bool enable, bool retain)
   111     { 
   112         getWeakRefs()->trackMe(enable, retain); 
   113     }
   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     };
   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);
   128 protected:
   129                             RefBase();
   130     virtual                 ~RefBase();
   132     //! Flags for extendObjectLifetime()
   133     enum {
   134         OBJECT_LIFETIME_WEAK    = 0x0001,
   135         OBJECT_LIFETIME_FOREVER = 0x0003
   136     };
   138             void            extendObjectLifetime(int32_t mode);
   140     //! Flags for onIncStrongAttempted()
   141     enum {
   142         FIRST_INC_STRONG = 0x0001
   143     };
   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);
   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 protected:
   181     inline ~LightRefBase() { }
   183 private:
   184     mutable volatile int32_t mCount;
   185 };
   187 // ---------------------------------------------------------------------------
   189 template <typename T>
   190 class sp
   191 {
   192 public:
   193     typedef typename RefBase::weakref_type weakref_type;
   195     inline sp() : m_ptr(0) { }
   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);
   202     ~sp();
   204     // Assignment
   206     sp& operator = (T* other);
   207     sp& operator = (const sp<T>& other);
   209     template<typename U> sp& operator = (const sp<U>& other);
   210     template<typename U> sp& operator = (U* other);
   212     //! Special optimization for use by ProcessState (and nobody else).
   213     void force_set(T* other);
   215     // Reset
   217     void clear();
   219     // Accessors
   221     inline  T&      operator* () const  { return *m_ptr; }
   222     inline  T*      operator-> () const { return m_ptr;  }
   223     inline  T*      get() const         { return m_ptr; }
   225     // Operators
   227     COMPARE(==)
   228     COMPARE(!=)
   229     COMPARE(>)
   230     COMPARE(<)
   231     COMPARE(<=)
   232     COMPARE(>=)
   234 private:    
   235     template<typename Y> friend class sp;
   236     template<typename Y> friend class wp;
   238     // Optimization for wp::promote().
   239     sp(T* p, weakref_type* refs);
   241     T*              m_ptr;
   242 };
   244 template <typename T>
   245 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
   247 // ---------------------------------------------------------------------------
   249 template <typename T>
   250 class wp
   251 {
   252 public:
   253     typedef typename RefBase::weakref_type weakref_type;
   255     inline wp() : m_ptr(0) { }
   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);
   264     ~wp();
   266     // Assignment
   268     wp& operator = (T* other);
   269     wp& operator = (const wp<T>& other);
   270     wp& operator = (const sp<T>& other);
   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);
   276     void set_object_and_refs(T* other, weakref_type* refs);
   278     // promotion to sp
   280     sp<T> promote() const;
   282     // Reset
   284     void clear();
   286     // Accessors
   288     inline  weakref_type* get_refs() const { return m_refs; }
   290     inline  T* unsafe_get() const { return m_ptr; }
   292     // Operators
   294     COMPARE_WEAK(==)
   295     COMPARE_WEAK(!=)
   296     COMPARE_WEAK(>)
   297     COMPARE_WEAK(<)
   298     COMPARE_WEAK(<=)
   299     COMPARE_WEAK(>=)
   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     }
   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     }
   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); }
   331 private:
   332     template<typename Y> friend class sp;
   333     template<typename Y> friend class wp;
   335     T*              m_ptr;
   336     weakref_type*   m_refs;
   337 };
   339 template <typename T>
   340 TextOutput& operator<<(TextOutput& to, const wp<T>& val);
   342 #undef COMPARE
   343 #undef COMPARE_WEAK
   345 // ---------------------------------------------------------------------------
   346 // No user serviceable parts below here.
   348 template<typename T>
   349 sp<T>::sp(T* other)
   350     : m_ptr(other)
   351 {
   352     if (other) other->incStrong(this);
   353 }
   355 template<typename T>
   356 sp<T>::sp(const sp<T>& other)
   357     : m_ptr(other.m_ptr)
   358 {
   359     if (m_ptr) m_ptr->incStrong(this);
   360 }
   362 template<typename T> template<typename U>
   363 sp<T>::sp(U* other) : m_ptr(other)
   364 {
   365     if (other) other->incStrong(this);
   366 }
   368 template<typename T> template<typename U>
   369 sp<T>::sp(const sp<U>& other)
   370     : m_ptr(other.m_ptr)
   371 {
   372     if (m_ptr) m_ptr->incStrong(this);
   373 }
   375 template<typename T>
   376 sp<T>::~sp()
   377 {
   378     if (m_ptr) m_ptr->decStrong(this);
   379 }
   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 }
   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 }
   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 }
   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 }
   418 template<typename T>    
   419 void sp<T>::force_set(T* other)
   420 {
   421     other->forceIncStrong(this);
   422     m_ptr = other;
   423 }
   425 template<typename T>
   426 void sp<T>::clear()
   427 {
   428     if (m_ptr) {
   429         m_ptr->decStrong(this);
   430         m_ptr = 0;
   431     }
   432 }
   434 template<typename T>
   435 sp<T>::sp(T* p, weakref_type* refs)
   436     : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
   437 {
   438 }
   440 template <typename T>
   441 inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
   442 {
   443     to << "sp<>(" << val.get() << ")";
   444     return to;
   445 }
   447 // ---------------------------------------------------------------------------
   449 template<typename T>
   450 wp<T>::wp(T* other)
   451     : m_ptr(other)
   452 {
   453     if (other) m_refs = other->createWeak(this);
   454 }
   456 template<typename T>
   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 }
   463 template<typename T>
   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 }
   472 template<typename T> template<typename U>
   473 wp<T>::wp(U* other)
   474     : m_ptr(other)
   475 {
   476     if (other) m_refs = other->createWeak(this);
   477 }
   479 template<typename T> template<typename U>
   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 }
   489 template<typename T> template<typename U>
   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 }
   498 template<typename T>
   499 wp<T>::~wp()
   500 {
   501     if (m_ptr) m_refs->decWeak(this);
   502 }
   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 }
   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 }
   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 }
   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 }
   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 }
   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 }
   574 template<typename T>
   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 }
   583 template<typename T>
   584 sp<T> wp<T>::promote() const
   585 {
   586     return sp<T>(m_ptr, m_refs);
   587 }
   589 template<typename T>
   590 void wp<T>::clear()
   591 {
   592     if (m_ptr) {
   593         m_refs->decWeak(this);
   594         m_ptr = 0;
   595     }
   596 }
   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 }
   605 }; // namespace android
   607 // ---------------------------------------------------------------------------
   609 #endif // ANDROID_REF_BASE_H

mercurial