Flutter Engine
The Flutter Engine
Public Member Functions | Protected Member Functions | List of all members
SkWeakRefCnt Class Reference

#include <SkWeakRefCnt.h>

Inheritance diagram for SkWeakRefCnt:
SkRefCnt SkRefCntBase PlacedWeakRefCnt SkTypeface DWriteFontTypeface SkRandomTypeface SkTypefaceProxy SkTypeface_Fontations SkTypeface_FreeType SkUserTypeface TestEmptyTypeface TestTypeface

Public Member Functions

 SkWeakRefCnt ()
 
 ~SkWeakRefCnt () override
 
bool try_ref () const
 
void weak_ref () const
 
void weak_unref () const
 
bool weak_expired () const
 
- Public Member Functions inherited from SkRefCntBase
 SkRefCntBase ()
 
virtual ~SkRefCntBase ()
 
bool unique () const
 
void ref () const
 
void unref () const
 

Protected Member Functions

virtual void weak_dispose () const
 

Detailed Description

SkWeakRefCnt is the base class for objects that may be shared by multiple objects. When an existing strong owner wants to share a reference, it calls ref(). When a strong owner wants to release its reference, it calls unref(). When the shared object's strong reference count goes to zero as the result of an unref() call, its (virtual) weak_dispose method 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.

In addition to strong ownership, an owner may instead obtain a weak reference by calling weak_ref(). A call to weak_ref() must be balanced by a call to weak_unref(). To obtain a strong reference from a weak reference, call try_ref(). If try_ref() returns true, the owner's pointer is now also a strong reference on which unref() must be called. Note that this does not affect the original weak reference, weak_unref() must still be called. When the weak reference count goes to zero, the object is deleted. While the weak reference count is positive and the strong reference count is zero the object still exists, but will be in the disposed state. It is up to the object to define what this means.

Note that a strong reference implicitly implies a weak reference. As a result, it is allowable for the owner of a strong ref to call try_ref(). This will have the same effect as calling ref(), but may be more expensive.

Example:

SkWeakRefCnt myRef = strongRef.weak_ref(); ... // strongRef.unref() may or may not be called if (myRef.try_ref()) { ... // use myRef myRef.unref(); } else { myRef is in the disposed state } myRef.weak_unref();

Definition at line 55 of file SkWeakRefCnt.h.

Constructor & Destructor Documentation

◆ SkWeakRefCnt()

SkWeakRefCnt::SkWeakRefCnt ( )
inline

Default construct, initializing the reference counts to 1. The strong references collectively hold one weak reference. When the strong reference count goes to zero, the collectively held weak reference is released.

Definition at line 62 of file SkWeakRefCnt.h.

62: SkRefCnt(), fWeakCnt(1) {}

◆ ~SkWeakRefCnt()

SkWeakRefCnt::~SkWeakRefCnt ( )
inlineoverride

Destruct, asserting that the weak reference count is 1.

Definition at line 66 of file SkWeakRefCnt.h.

66 {
67#ifdef SK_DEBUG
68 SkASSERT(getWeakCnt() == 1);
69 fWeakCnt.store(0, std::memory_order_relaxed);
70#endif
71 }
#define SkASSERT(cond)
Definition: SkAssert.h:116

Member Function Documentation

◆ try_ref()

bool SkWeakRefCnt::try_ref ( ) const
inline

Creates a strong reference from a weak reference, if possible. The caller must already be an owner. If try_ref() returns true the owner is in posession of an additional strong reference. Both the original reference and new reference must be properly unreferenced. If try_ref() returns false, no strong reference could be created and the owner's reference is in the same state as before the call.

Definition at line 103 of file SkWeakRefCnt.h.

103 {
104 if (atomic_conditional_acquire_strong_ref() != 0) {
105 // Acquire barrier (L/SL), if not provided above.
106 // Prevents subsequent code from happening before the increment.
107 return true;
108 }
109 return false;
110 }

◆ weak_dispose()

virtual void SkWeakRefCnt::weak_dispose ( ) const
inlineprotectedvirtual

Called when the strong reference count goes to zero. This allows the object to free any resources it may be holding. Weak references may still exist and their level of allowed access to the object is defined by the object's class.

Reimplemented in DWriteFontTypeface.

Definition at line 154 of file SkWeakRefCnt.h.

154 {
155 }

◆ weak_expired()

bool SkWeakRefCnt::weak_expired ( ) const
inline

Returns true if there are no strong references to the object. When this is the case all future calls to try_ref() will return false.

Definition at line 144 of file SkWeakRefCnt.h.

144 {
145 return fRefCnt.load(std::memory_order_relaxed) == 0;
146 }

◆ weak_ref()

void SkWeakRefCnt::weak_ref ( ) const
inline

Increment the weak reference count. Must be balanced by a call to weak_unref().

Definition at line 115 of file SkWeakRefCnt.h.

115 {
116 SkASSERT(getRefCnt() > 0);
117 SkASSERT(getWeakCnt() > 0);
118 // No barrier required.
119 (void)fWeakCnt.fetch_add(+1, std::memory_order_relaxed);
120 }

◆ weak_unref()

void SkWeakRefCnt::weak_unref ( ) const
inline

Decrement the weak reference count. If the weak 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.

Definition at line 127 of file SkWeakRefCnt.h.

127 {
128 SkASSERT(getWeakCnt() > 0);
129 // A release here acts in place of all releases we "should" have been doing in ref().
130 if (1 == fWeakCnt.fetch_add(-1, std::memory_order_acq_rel)) {
131 // Like try_ref(), the acquire is only needed on success, to make sure
132 // code in internal_dispose() doesn't happen before the decrement.
133#ifdef SK_DEBUG
134 // so our destructor won't complain
135 fWeakCnt.store(1, std::memory_order_relaxed);
136#endif
138 }
139 }
virtual void internal_dispose() const
Definition: SkRefCnt.h:94

The documentation for this class was generated from the following file: