media/omx-plugin/include/froyo/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(_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 }
    57 // ---------------------------------------------------------------------------
    59 class RefBase
    60 {
    61 public:
    62             void            incStrong(const void* id) const;
    63             void            decStrong(const void* id) const;
    65             void            forceIncStrong(const void* id) const;
    67             //! DEBUGGING ONLY: Get current strong ref count.
    68             int32_t         getStrongCount() const;
    70     class weakref_type
    71     {
    72     public:
    73         RefBase*            refBase() const;
    75         void                incWeak(const void* id);
    76         void                decWeak(const void* id);
    78         bool                attemptIncStrong(const void* id);
    80         //! This is only safe if you have set OBJECT_LIFETIME_FOREVER.
    81         bool                attemptIncWeak(const void* id);
    83         //! DEBUGGING ONLY: Get current weak ref count.
    84         int32_t             getWeakCount() const;
    86         //! DEBUGGING ONLY: Print references held on object.
    87         void                printRefs() const;
    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.
    96         void                trackMe(bool enable, bool retain);
    97     };
    99             weakref_type*   createWeak(const void* id) const;
   101             weakref_type*   getWeakRefs() const;
   103             //! DEBUGGING ONLY: Print references held on object.
   104     inline  void            printRefs() const { getWeakRefs()->printRefs(); }
   106             //! DEBUGGING ONLY: Enable tracking of object.
   107     inline  void            trackMe(bool enable, bool retain)
   108     { 
   109         getWeakRefs()->trackMe(enable, retain); 
   110     }
   112 protected:
   113                             RefBase();
   114     virtual                 ~RefBase();
   116     //! Flags for extendObjectLifetime()
   117     enum {
   118         OBJECT_LIFETIME_WEAK    = 0x0001,
   119         OBJECT_LIFETIME_FOREVER = 0x0003
   120     };
   122             void            extendObjectLifetime(int32_t mode);
   124     //! Flags for onIncStrongAttempted()
   125     enum {
   126         FIRST_INC_STRONG = 0x0001
   127     };
   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);
   134 private:
   135     friend class weakref_type;
   136     class weakref_impl;
   138                             RefBase(const RefBase& o);
   139             RefBase&        operator=(const RefBase& o);
   141         weakref_impl* const mRefs;
   142 };
   144 // ---------------------------------------------------------------------------
   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     }
   164 protected:
   165     inline ~LightRefBase() { }
   167 private:
   168     mutable volatile int32_t mCount;
   169 };
   171 // ---------------------------------------------------------------------------
   173 template <typename T>
   174 class sp
   175 {
   176 public:
   177     typedef typename RefBase::weakref_type weakref_type;
   179     inline sp() : m_ptr(0) { }
   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);
   186     ~sp();
   188     // Assignment
   190     sp& operator = (T* other);
   191     sp& operator = (const sp<T>& other);
   193     template<typename U> sp& operator = (const sp<U>& other);
   194     template<typename U> sp& operator = (U* other);
   196     //! Special optimization for use by ProcessState (and nobody else).
   197     void force_set(T* other);
   199     // Reset
   201     void clear();
   203     // Accessors
   205     inline  T&      operator* () const  { return *m_ptr; }
   206     inline  T*      operator-> () const { return m_ptr;  }
   207     inline  T*      get() const         { return m_ptr; }
   209     // Operators
   211     COMPARE(==)
   212     COMPARE(!=)
   213     COMPARE(>)
   214     COMPARE(<)
   215     COMPARE(<=)
   216     COMPARE(>=)
   218 private:    
   219     template<typename Y> friend class sp;
   220     template<typename Y> friend class wp;
   222     // Optimization for wp::promote().
   223     sp(T* p, weakref_type* refs);
   225     T*              m_ptr;
   226 };
   228 template <typename T>
   229 TextOutput& operator<<(TextOutput& to, const sp<T>& val);
   231 // ---------------------------------------------------------------------------
   233 template <typename T>
   234 class wp
   235 {
   236 public:
   237     typedef typename RefBase::weakref_type weakref_type;
   239     inline wp() : m_ptr(0) { }
   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);
   248     ~wp();
   250     // Assignment
   252     wp& operator = (T* other);
   253     wp& operator = (const wp<T>& other);
   254     wp& operator = (const sp<T>& other);
   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);
   260     void set_object_and_refs(T* other, weakref_type* refs);
   262     // promotion to sp
   264     sp<T> promote() const;
   266     // Reset
   268     void clear();
   270     // Accessors
   272     inline  weakref_type* get_refs() const { return m_refs; }
   274     inline  T* unsafe_get() const { return m_ptr; }
   276     // Operators
   278     COMPARE(==)
   279     COMPARE(!=)
   280     COMPARE(>)
   281     COMPARE(<)
   282     COMPARE(<=)
   283     COMPARE(>=)
   285 private:
   286     template<typename Y> friend class sp;
   287     template<typename Y> friend class wp;
   289     T*              m_ptr;
   290     weakref_type*   m_refs;
   291 };
   293 template <typename T>
   294 TextOutput& operator<<(TextOutput& to, const wp<T>& val);
   296 #undef COMPARE
   298 // ---------------------------------------------------------------------------
   299 // No user serviceable parts below here.
   301 template<typename T>
   302 sp<T>::sp(T* other)
   303     : m_ptr(other)
   304 {
   305     if (other) other->incStrong(this);
   306 }
   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 }
   315 template<typename T> template<typename U>
   316 sp<T>::sp(U* other) : m_ptr(other)
   317 {
   318     if (other) other->incStrong(this);
   319 }
   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 }
   328 template<typename T>
   329 sp<T>::~sp()
   330 {
   331     if (m_ptr) m_ptr->decStrong(this);
   332 }
   334 template<typename T>
   335 sp<T>& sp<T>::operator = (const sp<T>& other) {
   336     if (other.m_ptr) other.m_ptr->incStrong(this);
   337     if (m_ptr) m_ptr->decStrong(this);
   338     m_ptr = other.m_ptr;
   339     return *this;
   340 }
   342 template<typename T>
   343 sp<T>& sp<T>::operator = (T* other)
   344 {
   345     if (other) other->incStrong(this);
   346     if (m_ptr) m_ptr->decStrong(this);
   347     m_ptr = other;
   348     return *this;
   349 }
   351 template<typename T> template<typename U>
   352 sp<T>& sp<T>::operator = (const sp<U>& other)
   353 {
   354     if (other.m_ptr) other.m_ptr->incStrong(this);
   355     if (m_ptr) m_ptr->decStrong(this);
   356     m_ptr = other.m_ptr;
   357     return *this;
   358 }
   360 template<typename T> template<typename U>
   361 sp<T>& sp<T>::operator = (U* other)
   362 {
   363     if (other) other->incStrong(this);
   364     if (m_ptr) m_ptr->decStrong(this);
   365     m_ptr = other;
   366     return *this;
   367 }
   369 template<typename T>    
   370 void sp<T>::force_set(T* other)
   371 {
   372     other->forceIncStrong(this);
   373     m_ptr = other;
   374 }
   376 template<typename T>
   377 void sp<T>::clear()
   378 {
   379     if (m_ptr) {
   380         m_ptr->decStrong(this);
   381         m_ptr = 0;
   382     }
   383 }
   385 template<typename T>
   386 sp<T>::sp(T* p, weakref_type* refs)
   387     : m_ptr((p && refs->attemptIncStrong(this)) ? p : 0)
   388 {
   389 }
   391 template <typename T>
   392 inline TextOutput& operator<<(TextOutput& to, const sp<T>& val)
   393 {
   394     to << "sp<>(" << val.get() << ")";
   395     return to;
   396 }
   398 // ---------------------------------------------------------------------------
   400 template<typename T>
   401 wp<T>::wp(T* other)
   402     : m_ptr(other)
   403 {
   404     if (other) m_refs = other->createWeak(this);
   405 }
   407 template<typename T>
   408 wp<T>::wp(const wp<T>& other)
   409     : m_ptr(other.m_ptr), m_refs(other.m_refs)
   410 {
   411     if (m_ptr) m_refs->incWeak(this);
   412 }
   414 template<typename T>
   415 wp<T>::wp(const sp<T>& other)
   416     : m_ptr(other.m_ptr)
   417 {
   418     if (m_ptr) {
   419         m_refs = m_ptr->createWeak(this);
   420     }
   421 }
   423 template<typename T> template<typename U>
   424 wp<T>::wp(U* other)
   425     : m_ptr(other)
   426 {
   427     if (other) m_refs = other->createWeak(this);
   428 }
   430 template<typename T> template<typename U>
   431 wp<T>::wp(const wp<U>& other)
   432     : m_ptr(other.m_ptr)
   433 {
   434     if (m_ptr) {
   435         m_refs = other.m_refs;
   436         m_refs->incWeak(this);
   437     }
   438 }
   440 template<typename T> template<typename U>
   441 wp<T>::wp(const sp<U>& other)
   442     : m_ptr(other.m_ptr)
   443 {
   444     if (m_ptr) {
   445         m_refs = m_ptr->createWeak(this);
   446     }
   447 }
   449 template<typename T>
   450 wp<T>::~wp()
   451 {
   452     if (m_ptr) m_refs->decWeak(this);
   453 }
   455 template<typename T>
   456 wp<T>& wp<T>::operator = (T* other)
   457 {
   458     weakref_type* newRefs =
   459         other ? other->createWeak(this) : 0;
   460     if (m_ptr) m_refs->decWeak(this);
   461     m_ptr = other;
   462     m_refs = newRefs;
   463     return *this;
   464 }
   466 template<typename T>
   467 wp<T>& wp<T>::operator = (const wp<T>& other)
   468 {
   469     if (other.m_ptr) other.m_refs->incWeak(this);
   470     if (m_ptr) m_refs->decWeak(this);
   471     m_ptr = other.m_ptr;
   472     m_refs = other.m_refs;
   473     return *this;
   474 }
   476 template<typename T>
   477 wp<T>& wp<T>::operator = (const sp<T>& other)
   478 {
   479     weakref_type* newRefs =
   480         other != NULL ? other->createWeak(this) : 0;
   481     if (m_ptr) m_refs->decWeak(this);
   482     m_ptr = other.get();
   483     m_refs = newRefs;
   484     return *this;
   485 }
   487 template<typename T> template<typename U>
   488 wp<T>& wp<T>::operator = (U* other)
   489 {
   490     weakref_type* newRefs =
   491         other ? other->createWeak(this) : 0;
   492     if (m_ptr) m_refs->decWeak(this);
   493     m_ptr = other;
   494     m_refs = newRefs;
   495     return *this;
   496 }
   498 template<typename T> template<typename U>
   499 wp<T>& wp<T>::operator = (const wp<U>& other)
   500 {
   501     if (other.m_ptr) other.m_refs->incWeak(this);
   502     if (m_ptr) m_refs->decWeak(this);
   503     m_ptr = other.m_ptr;
   504     m_refs = other.m_refs;
   505     return *this;
   506 }
   508 template<typename T> template<typename U>
   509 wp<T>& wp<T>::operator = (const sp<U>& other)
   510 {
   511     weakref_type* newRefs =
   512         other != NULL ? other->createWeak(this) : 0;
   513     if (m_ptr) m_refs->decWeak(this);
   514     m_ptr = other.get();
   515     m_refs = newRefs;
   516     return *this;
   517 }
   519 template<typename T>
   520 void wp<T>::set_object_and_refs(T* other, weakref_type* refs)
   521 {
   522     if (other) refs->incWeak(this);
   523     if (m_ptr) m_refs->decWeak(this);
   524     m_ptr = other;
   525     m_refs = refs;
   526 }
   528 template<typename T>
   529 sp<T> wp<T>::promote() const
   530 {
   531     return sp<T>(m_ptr, m_refs);
   532 }
   534 template<typename T>
   535 void wp<T>::clear()
   536 {
   537     if (m_ptr) {
   538         m_refs->decWeak(this);
   539         m_ptr = 0;
   540     }
   541 }
   543 template <typename T>
   544 inline TextOutput& operator<<(TextOutput& to, const wp<T>& val)
   545 {
   546     to << "wp<>(" << val.unsafe_get() << ")";
   547     return to;
   548 }
   550 }; // namespace android
   552 // ---------------------------------------------------------------------------
   554 #endif // ANDROID_REF_BASE_H

mercurial