struct State {
global: Global,
accounts: SlotMap<AId, ARecord>,
}Expand description
Memory tracker inner, including mutable state
§Module internal documentation
§Data structure
MemoryQuotaTrackercontains mutex-protectedState.- The
Statecontains aSlotMapof account recordsARecord. - Each
ARecordcontains aSlotMapof participant recordsPRecord.
The handles Account, WeakAccount, and Participation,
each contain a reference (Arc/Weak) to the MemoryQuotaTracker,
and the necessary slotmap keys.
The ARecord and PRecord each contain a reference count,
which is used to clean up when all the handles are gone.
The slotmap keys which count for the reference count (ie, strong references)
are stored as refcount::Ref,
which helps assure correct reference counting.
(Bare ids AId and PId are weak references.)
§Data structure lookup
Given a reference to the tracker, and some ids, the macro find_in_tracker!
is used to obtain mutable references to the ARecord and (if applicable) PRecord.
§Bookkeeping
We use separate types for quantities of memory in various “states”, rather than working with raw quantities.
The types, and the legitimate transactions, are in bookkeeping.
§Reentrancy (esp. Drop and Clone)
When the handle structs are dropped or cloned, they must manipulate the refcount(s).
So they must take the lock.
Therefore, an Account and Participation may not be dropped with the lock held!
Internally, this is actually fairly straightforward: we take handles by reference, and constructors only make them at the last moment on return, so our internal code here, in this module, doesn’t have owned handles.
We also need to worry about reentrantly reentering the tracker code, from user code.
The user supplies a dyn IsParticipant.
The principal methods are from IsParticipant,
for which we handle reentrancy in the docs.
But we also implicitly invoke its Drop impl, which might in turn drop stuff of ours,
such as Accounts and Participations, whose Drop impls need to take our lock.
To make sure this isn’t done reentrantly, we have a special newtype around it,
and defer some of our drops during reclaim.
That’s in drop_reentrancy and tracker::reclaim::deferred_drop.
The Debug impl isn’t of concern, since we don’t call it ourselves.
And we don’t rely on it being Clone, since it’s in an Arc.
§Drop bombs
With #[cfg(test)], several of our types have “drop bombs”:
they cause a panic if dropped inappropriately.
This is intended to detect bad code paths during testing.
Fields§
§global: GlobalGlobal parts of state
Broken out to allow passing both
&mut Global and &mut ARecord/&mut PRecord
to some function(s).
accounts: SlotMap<AId, ARecord>Accounts
Implementations§
Source§impl State
impl State
Sourcefn get_aid_and_children_recursively(&self, parent_aid: AId) -> HashSet<AId>
fn get_aid_and_children_recursively(&self, parent_aid: AId) -> HashSet<AId>
Obtain all of the descendants of parent_aid according to the Child relation
The returned HashSet includes parent_aid, its children,
their children, and so on.
Used in the reclamation algorithm in reclaim.
Sourcefn prepare_parent_aid(&mut self, parent: &Account) -> Result<AId>
fn prepare_parent_aid(&mut self, parent: &Account) -> Result<AId>
Find and check the requested parent’s account ID
This function is responsible for garbage collecting dead children
from parent’s children. On successful return, a new child
can be added without extending children.
This is called in preparation for adding another account
to parent’s list of child accounts.
Returns an error if the specified parent account is not enabled,
or if it has been torn down.
Trait Implementations§
Auto Trait Implementations§
impl Freeze for State
impl !RefUnwindSafe for State
impl Send for State
impl Sync for State
impl Unpin for State
impl UnsafeUnpin for State
impl !UnwindSafe for State
Blanket Implementations§
Source§impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedExplicit<'a, E> for Twhere
T: 'a,
Source§impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
impl<'a, T, E> AsTaggedImplicit<'a, E> for Twhere
T: 'a,
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
Source§fn in_current_span(self) -> Instrumented<Self> ⓘ
fn in_current_span(self) -> Instrumented<Self> ⓘ
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more