aboutsummaryrefslogtreecommitdiffhomepage
path: root/include/core/SkRefCnt.h
diff options
context:
space:
mode:
authorGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-16 18:21:56 +0000
committerGravatar bungeman@google.com <bungeman@google.com@2bbb7eff-a529-9590-31e7-b0007b416f81>2012-05-16 18:21:56 +0000
commita02bc1519cf49afa31fb38bed097dd5014880d04 (patch)
tree64d0638ce6c287317467d07bb5f7aeeb290d7940 /include/core/SkRefCnt.h
parentb2aacb6dc29f853e3f37fad208ad8fe8c8138a03 (diff)
WeakRefCnt
Diffstat (limited to 'include/core/SkRefCnt.h')
-rw-r--r--include/core/SkRefCnt.h39
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;
};