LCOV - code coverage report
Current view: directory - gfx/skia/include/core - SkRefCnt.h (source / functions) Found Hit Coverage
Test: app.info Lines: 28 0 0.0 %
Date: 2012-06-02 Functions: 45 0 0.0 %

       1                 : 
       2                 : /*
       3                 :  * Copyright 2006 The Android Open Source Project
       4                 :  *
       5                 :  * Use of this source code is governed by a BSD-style license that can be
       6                 :  * found in the LICENSE file.
       7                 :  */
       8                 : 
       9                 : 
      10                 : #ifndef SkRefCnt_DEFINED
      11                 : #define SkRefCnt_DEFINED
      12                 : 
      13                 : #include "SkThread.h"
      14                 : 
      15                 : /** \class SkRefCnt
      16                 : 
      17                 :     SkRefCnt is the base class for objects that may be shared by multiple
      18                 :     objects. When a new owner wants a reference, it calls ref(). When an owner
      19                 :     wants to release its reference, it calls unref(). When the shared object's
      20                 :     reference count goes to zero as the result of an unref() call, its (virtual)
      21                 :     destructor is called. It is an error for the destructor to be called
      22                 :     explicitly (or via the object going out of scope on the stack or calling
      23                 :     delete) if getRefCnt() > 1.
      24                 : */
      25                 : class SK_API SkRefCnt : SkNoncopyable {
      26                 : public:
      27                 :     /** Default construct, initializing the reference count to 1.
      28                 :     */
      29               0 :     SkRefCnt() : fRefCnt(1) {}
      30                 : 
      31                 :     /**  Destruct, asserting that the reference count is 1.
      32                 :     */
      33               0 :     virtual ~SkRefCnt() {
      34                 : #ifdef SK_DEBUG
      35               0 :         SkASSERT(fRefCnt == 1);
      36               0 :         fRefCnt = 0;    // illegal value, to catch us if we reuse after delete
      37                 : #endif
      38               0 :     }
      39                 : 
      40                 :     /** Return the reference count.
      41                 :     */
      42               0 :     int32_t getRefCnt() const { return fRefCnt; }
      43                 : 
      44                 :     /** Increment the reference count. Must be balanced by a call to unref().
      45                 :     */
      46               0 :     void ref() const {
      47               0 :         SkASSERT(fRefCnt > 0);
      48               0 :         sk_atomic_inc(&fRefCnt);
      49               0 :     }
      50                 : 
      51                 :     /** Decrement the reference count. If the reference count is 1 before the
      52                 :         decrement, then call delete on the object. Note that if this is the
      53                 :         case, then the object needs to have been allocated via new, and not on
      54                 :         the stack.
      55                 :     */
      56               0 :     void unref() const {
      57               0 :         SkASSERT(fRefCnt > 0);
      58               0 :         if (sk_atomic_dec(&fRefCnt) == 1) {
      59               0 :             fRefCnt = 1;    // so our destructor won't complain
      60               0 :             SkDELETE(this);
      61                 :         }
      62               0 :     }
      63                 : 
      64                 :     void validate() const {
      65                 :         SkASSERT(fRefCnt > 0);
      66                 :     }
      67                 : 
      68                 : private:
      69                 :     mutable int32_t fRefCnt;
      70                 : };
      71                 : 
      72                 : ///////////////////////////////////////////////////////////////////////////////
      73                 : 
      74                 : /** Helper macro to safely assign one SkRefCnt[TS]* to another, checking for
      75                 :     null in on each side of the assignment, and ensuring that ref() is called
      76                 :     before unref(), in case the two pointers point to the same object.
      77                 :  */
      78                 : #define SkRefCnt_SafeAssign(dst, src)   \
      79                 :     do {                                \
      80                 :         if (src) src->ref();            \
      81                 :         if (dst) dst->unref();          \
      82                 :         dst = src;                      \
      83                 :     } while (0)
      84                 : 
      85                 : 
      86                 : /** Check if the argument is non-null, and if so, call obj->ref()
      87                 :  */
      88               0 : template <typename T> static inline void SkSafeRef(T* obj) {
      89               0 :     if (obj) {
      90               0 :         obj->ref();
      91                 :     }
      92               0 : }
      93                 : 
      94                 : /** Check if the argument is non-null, and if so, call obj->unref()
      95                 :  */
      96               0 : template <typename T> static inline void SkSafeUnref(T* obj) {
      97               0 :     if (obj) {
      98               0 :         obj->unref();
      99                 :     }
     100               0 : }
     101                 : 
     102                 : ///////////////////////////////////////////////////////////////////////////////
     103                 : 
     104                 : /**
     105                 :  *  Utility class that simply unref's its argument in the destructor.
     106                 :  */
     107                 : template <typename T> class SkAutoTUnref : SkNoncopyable {
     108                 : public:
     109               0 :     explicit SkAutoTUnref(T* obj = NULL) : fObj(obj) {}
     110               0 :     ~SkAutoTUnref() { SkSafeUnref(fObj); }
     111                 : 
     112                 :     T* get() const { return fObj; }
     113                 : 
     114                 :     void reset(T* obj) {
     115                 :         SkSafeUnref(fObj);
     116                 :         fObj = obj;
     117                 :     }
     118                 : 
     119                 :     /**
     120                 :      *  Return the hosted object (which may be null), transferring ownership.
     121                 :      *  The reference count is not modified, and the internal ptr is set to NULL
     122                 :      *  so unref() will not be called in our destructor. A subsequent call to
     123                 :      *  detach() will do nothing and return null.
     124                 :      */
     125                 :     T* detach() {
     126                 :         T* obj = fObj;
     127                 :         fObj = NULL;
     128                 :         return obj;
     129                 :     }
     130                 : 
     131                 : private:
     132                 :     T*  fObj;
     133                 : };
     134                 : 
     135               0 : class SkAutoUnref : public SkAutoTUnref<SkRefCnt> {
     136                 : public:
     137               0 :     SkAutoUnref(SkRefCnt* obj) : SkAutoTUnref<SkRefCnt>(obj) {}
     138                 : };
     139                 : 
     140                 : class SkAutoRef : SkNoncopyable {
     141                 : public:
     142                 :     SkAutoRef(SkRefCnt* obj) : fObj(obj) { SkSafeRef(obj); }
     143                 :     ~SkAutoRef() { SkSafeUnref(fObj); }
     144                 : private:
     145                 :     SkRefCnt* fObj;
     146                 : };
     147                 : 
     148                 : /** Wrapper class for SkRefCnt pointers. This manages ref/unref of a pointer to
     149                 :     a SkRefCnt (or subclass) object.
     150                 :  */
     151                 : template <typename T> class SkRefPtr {
     152                 : public:
     153                 :     SkRefPtr() : fObj(NULL) {}
     154                 :     SkRefPtr(T* obj) : fObj(obj) { SkSafeRef(fObj); }
     155                 :     SkRefPtr(const SkRefPtr& o) : fObj(o.fObj) { SkSafeRef(fObj); }
     156                 :     ~SkRefPtr() { SkSafeUnref(fObj); }
     157                 : 
     158                 :     SkRefPtr& operator=(const SkRefPtr& rp) {
     159                 :         SkRefCnt_SafeAssign(fObj, rp.fObj);
     160                 :         return *this;
     161                 :     }
     162                 :     SkRefPtr& operator=(T* obj) {
     163                 :         SkRefCnt_SafeAssign(fObj, obj);
     164                 :         return *this;
     165                 :     }
     166                 : 
     167                 :     T* get() const { return fObj; }
     168                 :     T& operator*() const { return *fObj; }
     169                 :     T* operator->() const { return fObj; }
     170                 : 
     171                 :     typedef T* SkRefPtr::*unspecified_bool_type;
     172                 :     operator unspecified_bool_type() const {
     173                 :         return fObj ? &SkRefPtr::fObj : NULL;
     174                 :     }
     175                 : 
     176                 : private:
     177                 :     T* fObj;
     178                 : };
     179                 : 
     180                 : #endif
     181                 : 

Generated by: LCOV version 1.7