diff options
author | 2012-05-16 18:21:56 +0000 | |
---|---|---|
committer | 2012-05-16 18:21:56 +0000 | |
commit | a02bc1519cf49afa31fb38bed097dd5014880d04 (patch) | |
tree | 64d0638ce6c287317467d07bb5f7aeeb290d7940 /include/core/SkRefCnt.h | |
parent | b2aacb6dc29f853e3f37fad208ad8fe8c8138a03 (diff) |
WeakRefCnt
http://codereview.appspot.com/5649046/
git-svn-id: http://skia.googlecode.com/svn/trunk@3978 2bbb7eff-a529-9590-31e7-b0007b416f81
Diffstat (limited to 'include/core/SkRefCnt.h')
-rw-r--r-- | include/core/SkRefCnt.h | 39 |
1 files changed, 26 insertions, 13 deletions
diff --git a/include/core/SkRefCnt.h b/include/core/SkRefCnt.h index 71a2443584..384b3be2eb 100644 --- a/include/core/SkRefCnt.h +++ b/include/core/SkRefCnt.h @@ -15,12 +15,12 @@ /** \class SkRefCnt SkRefCnt is the base class for objects that may be shared by multiple - objects. When a new owner wants a reference, it calls ref(). When an owner - wants to release its reference, it calls unref(). When the shared object's - reference count goes to zero as the result of an unref() call, its (virtual) - destructor is called. It is an error for the destructor to be called - explicitly (or via the object going out of scope on the stack or calling - delete) if getRefCnt() > 1. + objects. When an existing owner wants to share a reference, it calls ref(). + When an owner wants to release its reference, it calls unref(). When the + shared object's reference count goes to zero as the result of an unref() + call, its (virtual) destructor is called. It is an error for the + destructor to be called explicitly (or via the object going out of scope on + the stack or calling delete) if getRefCnt() > 1. */ class SK_API SkRefCnt : SkNoncopyable { public: @@ -28,7 +28,7 @@ public: */ SkRefCnt() : fRefCnt(1) {} - /** Destruct, asserting that the reference count is 1. + /** Destruct, asserting that the reference count is 1. */ virtual ~SkRefCnt() { #ifdef SK_DEBUG @@ -45,19 +45,21 @@ public: */ void ref() const { SkASSERT(fRefCnt > 0); - sk_atomic_inc(&fRefCnt); + sk_atomic_inc(&fRefCnt); // No barrier required. } /** Decrement the reference count. If the reference count is 1 before the - decrement, then call delete on the object. Note that if this is the - case, then the object needs to have been allocated via new, and not on - the stack. + decrement, then delete the object. Note that if this is the case, then + the object needs to have been allocated via new, and not on the stack. */ void unref() const { SkASSERT(fRefCnt > 0); + // Release barrier (SL/S), if not provided below. if (sk_atomic_dec(&fRefCnt) == 1) { - fRefCnt = 1; // so our destructor won't complain - SkDELETE(this); + // Aquire barrier (L/SL), if not provided above. + // Prevents code in dispose from happening before the decrement. + sk_membar_aquire__after_atomic_dec(); + internal_dispose(); } } @@ -66,6 +68,17 @@ public: } private: + /** Called when the ref count goes to 0. + */ + virtual void internal_dispose() const { +#ifdef SK_DEBUG + // so our destructor won't complain + fRefCnt = 1; +#endif + SkDELETE(this); + } + friend class SkWeakRefCnt; + mutable int32_t fRefCnt; }; |