3#include <xrpl/beast/utility/instrumentation.h>
249 auto prevIntVal =
refCounts_.load(std::memory_order_acquire);
255 "xrpl::IntrusiveRefCounts::releaseStrongRef : previous ref "
261 if (prevVal.
weak == 0)
272 if (
refCounts_.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel))
279 "xrpl::IntrusiveRefCounts::releaseStrongRef : not in partial "
293 auto prevIntVal =
refCounts_.load(std::memory_order_acquire);
311 "xrpl::IntrusiveRefCounts::addWeakReleaseStrongRef : not in "
314 auto nextIntVal = prevIntVal + kDelta;
318 if (prevVal.
weak == 0)
328 if (
refCounts_.compare_exchange_weak(prevIntVal, nextIntVal, std::memory_order_acq_rel))
332 "xrpl::IntrusiveRefCounts::addWeakReleaseStrongRef : not "
333 "started partial destroy");
344 if (prev.weak == 1 && prev.strong == 0)
346 if (prev.partialDestroyStartedBit == 0u)
351 refCounts_.wait(prevIntVal, std::memory_order_acquire);
352 prevIntVal =
refCounts_.load(std::memory_order_acquire);
355 if (prev.partialDestroyFinishedBit == 0u)
372 while (!
refCounts_.compare_exchange_weak(curValue, desiredValue, std::memory_order_acq_rel))
375 if (prev.strong == 0u)
400 auto v =
refCounts_.load(std::memory_order_acquire);
402 (!(v &
kValueMask)),
"xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : count must be zero");
404 XRPL_ASSERT((!t || t ==
kTagMask),
"xrpl::IntrusiveRefCounts::~IntrusiveRefCounts : valid tag");
418 "xrpl::IntrusiveRefCounts::RefCountPair(FieldType) : inputs inside "
429 "xrpl::IntrusiveRefCounts::RefCountPair(CountType, CountType) : "
430 "inputs inside range");
438 "xrpl::IntrusiveRefCounts::RefCountPair::combinedValue : inputs "
455 "xrpl::partialDestructorFinished : not a weak ref");
461 self.refCounts_.notify_one();
Use hash_* containers for keys that do not need a cryptographically secure hashing algorithm.
ReleaseStrongRefAction
Action to perform when releasing a strong pointer.
ReleaseWeakRefAction
Action to perform when releasing a weak pointer.
Unpack the count and tag fields from the packed atomic integer form.
FieldType combinedValue() const noexcept
Convert back to the packed integer form.
RefCountPair(FieldType v) noexcept
static constexpr CountType kMaxStrongValue
FieldType partialDestroyStartedBit
The partialDestroyStartedBit is set to on when the partial destroy function is started.
static constexpr CountType kCheckStrongMaxValue
Put an extra margin to detect when running up against limits.
FieldType partialDestroyFinishedBit
The partialDestroyFinishedBit is set to on when the partial destroy function has finished.
static constexpr CountType kMaxWeakValue
static constexpr CountType kCheckWeakMaxValue
Implement the strong count, weak count, and bit flags for an intrusive pointer.
bool checkoutStrongRefFromWeak() const noexcept
static constexpr FieldType kPartialDestroyFinishedMask
Flag that is set when the partialDestroy function has finished running.
static constexpr FieldType kWeakMask
Mask that will zero out everything except the weak count.
static constexpr size_t kWeakCountNumBits
ReleaseStrongRefAction addWeakReleaseStrongRef() const
static constexpr FieldType kTagMask
Mask that will zero out all the count bits and leave the tag bits unchanged.
void addWeakRef() const noexcept
std::atomic< FieldType > refCounts_
refCounts consists of four fields that are treated atomically:
static constexpr FieldType kStrongDelta
Amount to change the strong count when adding or releasing a reference.
bool expired() const noexcept
static constexpr FieldType kStrongMask
Mask that will zero out everything except the strong count.
friend void partialDestructorFinished(T **o)
static constexpr size_t kFieldTypeBits
virtual ~IntrusiveRefCounts() noexcept
static constexpr FieldType kWeakDelta
Amount to change the weak count when adding or releasing a reference.
static constexpr FieldType kValueMask
Mask that will zero out the tag bits and leave the count bits unchanged.
ReleaseWeakRefAction releaseWeakRef() const
ReleaseStrongRefAction releaseStrongRef() const
void addStrongRef() const noexcept
std::size_t useCount() const noexcept
static constexpr FieldType kPartialDestroyStartedMask
Flag that is set when the partialDestroy function has started running (or is about to start running).
static constexpr FieldType kOne
static constexpr size_t kStrongCountNumBits