rippled
Loading...
Searching...
No Matches
Classes | Public Member Functions | Private Types | Private Attributes | Static Private Attributes | Friends | List of all members
ripple::IntrusiveRefCounts Struct Reference

Implement the strong count, weak count, and bit flags for an intrusive pointer. More...

#include <IntrusiveRefCounts.h>

Inheritance diagram for ripple::IntrusiveRefCounts:
Inheritance graph
[legend]
Collaboration diagram for ripple::IntrusiveRefCounts:
Collaboration graph
[legend]

Classes

struct  RefCountPair
 Unpack the count and tag fields from the packed atomic integer form. More...
 

Public Member Functions

virtual ~IntrusiveRefCounts () noexcept
 
void addStrongRef () const noexcept
 
void addWeakRef () const noexcept
 
ReleaseStrongRefAction releaseStrongRef () const
 
ReleaseStrongRefAction addWeakReleaseStrongRef () const
 
ReleaseWeakRefAction releaseWeakRef () const
 
bool checkoutStrongRefFromWeak () const noexcept
 
bool expired () const noexcept
 
std::size_t use_count () const noexcept
 

Private Types

using CountType = std::uint16_t
 
using FieldType = std::uint32_t
 

Private Attributes

std::atomic< FieldTyperefCounts {strongDelta}
 refCounts consists of four fields that are treated atomically:
 

Static Private Attributes

static constexpr size_t StrongCountNumBits = sizeof(CountType) * 8
 
static constexpr size_t WeakCountNumBits = StrongCountNumBits - 2
 
static constexpr size_t FieldTypeBits = sizeof(FieldType) * 8
 
static constexpr FieldType one = 1
 
static constexpr FieldType strongDelta = 1
 Amount to change the strong count when adding or releasing a reference.
 
static constexpr FieldType weakDelta = (one << StrongCountNumBits)
 Amount to change the weak count when adding or releasing a reference.
 
static constexpr FieldType partialDestroyStartedMask
 Flag that is set when the partialDestroy function has started running (or is about to start running).
 
static constexpr FieldType partialDestroyFinishedMask
 Flag that is set when the partialDestroy function has finished running.
 
static constexpr FieldType tagMask
 Mask that will zero out all the count bits and leave the tag bits unchanged.
 
static constexpr FieldType valueMask = ~tagMask
 Mask that will zero out the tag bits and leave the count bits unchanged.
 
static constexpr FieldType strongMask
 Mask that will zero out everything except the strong count.
 
static constexpr FieldType weakMask
 Mask that will zero out everything except the weak count.
 

Friends

template<class T >
void partialDestructorFinished (T **o)
 

Detailed Description

Implement the strong count, weak count, and bit flags for an intrusive pointer.

A class can satisfy the requirements of a ripple::IntrusivePointer by inheriting from this class.

Definition at line 59 of file IntrusiveRefCounts.h.

Member Typedef Documentation

◆ CountType

Definition at line 120 of file IntrusiveRefCounts.h.

◆ FieldType

Definition at line 123 of file IntrusiveRefCounts.h.

Constructor & Destructor Documentation

◆ ~IntrusiveRefCounts()

ripple::IntrusiveRefCounts::~IntrusiveRefCounts ( )
virtualnoexcept

Definition at line 424 of file IntrusiveRefCounts.h.

Member Function Documentation

◆ addStrongRef()

void ripple::IntrusiveRefCounts::addStrongRef ( ) const
noexcept

Definition at line 251 of file IntrusiveRefCounts.h.

◆ addWeakRef()

void ripple::IntrusiveRefCounts::addWeakRef ( ) const
noexcept

Definition at line 257 of file IntrusiveRefCounts.h.

◆ releaseStrongRef()

ReleaseStrongRefAction ripple::IntrusiveRefCounts::releaseStrongRef ( ) const

Definition at line 263 of file IntrusiveRefCounts.h.

◆ addWeakReleaseStrongRef()

ReleaseStrongRefAction ripple::IntrusiveRefCounts::addWeakReleaseStrongRef ( ) const

Definition at line 312 of file IntrusiveRefCounts.h.

◆ releaseWeakRef()

ReleaseWeakRefAction ripple::IntrusiveRefCounts::releaseWeakRef ( ) const

Definition at line 366 of file IntrusiveRefCounts.h.

◆ checkoutStrongRefFromWeak()

bool ripple::IntrusiveRefCounts::checkoutStrongRefFromWeak ( ) const
noexcept

Definition at line 393 of file IntrusiveRefCounts.h.

◆ expired()

bool ripple::IntrusiveRefCounts::expired ( ) const
noexcept

Definition at line 411 of file IntrusiveRefCounts.h.

◆ use_count()

std::size_t ripple::IntrusiveRefCounts::use_count ( ) const
noexcept

Definition at line 418 of file IntrusiveRefCounts.h.

Friends And Related Symbol Documentation

◆ partialDestructorFinished

template<class T >
void partialDestructorFinished ( T **  o)
friend

Definition at line 479 of file IntrusiveRefCounts.h.

Member Data Documentation

◆ StrongCountNumBits

constexpr size_t ripple::IntrusiveRefCounts::StrongCountNumBits = sizeof(CountType) * 8
staticconstexprprivate

Definition at line 121 of file IntrusiveRefCounts.h.

◆ WeakCountNumBits

constexpr size_t ripple::IntrusiveRefCounts::WeakCountNumBits = StrongCountNumBits - 2
staticconstexprprivate

Definition at line 122 of file IntrusiveRefCounts.h.

◆ FieldTypeBits

constexpr size_t ripple::IntrusiveRefCounts::FieldTypeBits = sizeof(FieldType) * 8
staticconstexprprivate

Definition at line 124 of file IntrusiveRefCounts.h.

◆ one

constexpr FieldType ripple::IntrusiveRefCounts::one = 1
staticconstexprprivate

Definition at line 125 of file IntrusiveRefCounts.h.

◆ refCounts

std::atomic<FieldType> ripple::IntrusiveRefCounts::refCounts {strongDelta}
mutableprivate

refCounts consists of four fields that are treated atomically:

  1. Strong count. This is a count of the number of shared pointers that hold a reference to this object. When the strong counts goes to zero, if the weak count is zero, the destructor is run. If the weak count is non-zero when the strong count goes to zero then the partialDestructor is run.
  2. Weak count. This is a count of the number of weak pointer that hold a reference to this object. When the weak count goes to zero and the strong count is also zero, then the destructor is run.
  3. Partial destroy started bit. This bit is set if the partialDestructor function has been started (or is about to be started). This is used to prevent the destructor from running concurrently with the partial destructor. This can easily happen when the last strong pointer release its reference in one thread and starts the partialDestructor, while in another thread the last weak pointer goes out of scope and starts the destructor while the partialDestructor is still running. Both a start and finished bit is needed to handle a corner-case where the last strong pointer goes out of scope, then then last weakPointer goes out of scope, but this happens before the partialDestructor bit is set. It would be possible to use a single bit if it could also be set atomically when the strong count goes to zero and the weak count is non-zero, but that would add complexity (and likely slow down common cases as well).
  4. Partial destroy finished bit. This bit is set when the partialDestructor has finished running. See (3) above for more information.

Definition at line 160 of file IntrusiveRefCounts.h.

◆ strongDelta

constexpr FieldType ripple::IntrusiveRefCounts::strongDelta = 1
staticconstexprprivate

Amount to change the strong count when adding or releasing a reference.

Note: The strong count is stored in the low StrongCountNumBits bits of refCounts

Definition at line 167 of file IntrusiveRefCounts.h.

◆ weakDelta

constexpr FieldType ripple::IntrusiveRefCounts::weakDelta = (one << StrongCountNumBits)
staticconstexprprivate

Amount to change the weak count when adding or releasing a reference.

Note: The weak count is stored in the high WeakCountNumBits bits of refCounts

Definition at line 174 of file IntrusiveRefCounts.h.

◆ partialDestroyStartedMask

constexpr FieldType ripple::IntrusiveRefCounts::partialDestroyStartedMask
staticconstexprprivate
Initial value:
=
(one << (FieldTypeBits - 1))
static constexpr size_t FieldTypeBits
static constexpr FieldType one

Flag that is set when the partialDestroy function has started running (or is about to start running).

See description of the refCounts field for a fuller description of this field.

Definition at line 182 of file IntrusiveRefCounts.h.

◆ partialDestroyFinishedMask

constexpr FieldType ripple::IntrusiveRefCounts::partialDestroyFinishedMask
staticconstexprprivate
Initial value:
=
(one << (FieldTypeBits - 2))

Flag that is set when the partialDestroy function has finished running.

See description of the refCounts field for a fuller description of this field.

Definition at line 190 of file IntrusiveRefCounts.h.

◆ tagMask

constexpr FieldType ripple::IntrusiveRefCounts::tagMask
staticconstexprprivate
Initial value:
=
static constexpr FieldType partialDestroyFinishedMask
Flag that is set when the partialDestroy function has finished running.
static constexpr FieldType partialDestroyStartedMask
Flag that is set when the partialDestroy function has started running (or is about to start running).

Mask that will zero out all the count bits and leave the tag bits unchanged.

Definition at line 196 of file IntrusiveRefCounts.h.

◆ valueMask

constexpr FieldType ripple::IntrusiveRefCounts::valueMask = ~tagMask
staticconstexprprivate

Mask that will zero out the tag bits and leave the count bits unchanged.

Definition at line 202 of file IntrusiveRefCounts.h.

◆ strongMask

constexpr FieldType ripple::IntrusiveRefCounts::strongMask
staticconstexprprivate
Initial value:
=
static constexpr size_t StrongCountNumBits
static constexpr FieldType valueMask
Mask that will zero out the tag bits and leave the count bits unchanged.

Mask that will zero out everything except the strong count.

Definition at line 206 of file IntrusiveRefCounts.h.

◆ weakMask

constexpr FieldType ripple::IntrusiveRefCounts::weakMask
staticconstexprprivate
Initial value:
=
static constexpr size_t WeakCountNumBits

Mask that will zero out everything except the weak count.

Definition at line 211 of file IntrusiveRefCounts.h.