cheatah
Class

memory::Lease

The only handle to an owned object — a move-only RAII lease granted by an Owner.

M is read (shared) or write/write_renewable (exclusive). Reads go through read(...); a write lease sets through write(...). The lease holds a direct pointer to the object plus the release callback it fires on destruction.

Template parameters
T

the owned type (Ownable).

M

the mode.

Functions

fn Lease · 3 overloads
Lease(T *obj, std::shared_ptr< detail::Gate > gate, std::function< void()> release) noexceptsource#
Lease(Lease &&o) noexceptsource#
Lease(const Lease &)=deletesource#

The owner's grant path (called only by Owner).

Complexity

O(1).

Allocation

none.

Parameters
obj

pointer to the owned object.

gate

the generation gate that carries the yield signal.

release

callback fired once on destruction to tell the owner this lease is done.

Concurrency

called by the owner with its coordinator mutex held — never construct one yourself.

fn operator= · 2 overloads
Lease & operator=(Lease &&o) noexceptsource#
Lease & operator=(const Lease &)=deletesource#

Move-assign: release ours, then take over o's grant.

Parameters
o

source.

Returns

*this.

Complexity

O(1).

Allocation

none.

fn ~Lease() source#

Release the lease (fires the owner's release callback if still held).

Complexity

O(1).

Allocation

none.

Concurrency

the release callback takes the owner's coordinator mutex and wakes waiting requests (a draining writer proceeds once the last reader releases here).

fn read · 3 overloads
const T & read() constsource#
const auto & read(std::size_t index) constsource#
const auto & read(K &&key) constsource#

Read the whole object.

Available on every lease.

Returns

a const T& — never a copy or T*.

Complexity

O(1).

Allocation

none.

Concurrency

race-free while the lease is held: a writer cannot proceed until this lease releases (yielding on !valid() is cooperative, not forced). No lock is taken here.

fn const auto & read_front() const source#

Read the first element (containers with front(): vector / deque / list / string …).

Returns

a const reference to the first element.

Complexity

O(1).

Allocation

none.

fn const auto & read_back() const source#

Read the last element (containers with back()).

Returns

a const reference to the last element.

Complexity

O(1).

Allocation

none.

fn write · 3 overloads
void write(T value)source#
void write(std::size_t index, V &&value)source#
void write(K &&key, V &&value)source#

Replace the whole object: w.write(value).

The primary write form. Write / write_renewable only.

Parameters
value

the new value (moved in).

Complexity

O(1) plus assigning value.

Allocation

whatever T's assignment allocates.

Concurrency

exclusive: no reader or other writer coexists while this lease is valid. A writer that observed !valid() (an immediate-write preempted it) must wait for valid() to flip back before writing again — writing while suspended races with the immediate-write.

fn bool valid() const noexcept source#

Still ours?

true until the owner asks us to yield (a writer waiting; an immediate-write). The holder observing !valid() is how the owner learns it has paused.

Returns

whether the lease is still valid.

Complexity

O(1).

Allocation

none.

Concurrency

an atomic acquire load; the first observation of a stop acks and wakes the owner (that one call briefly takes the owner's mutex) — polling this from the holding thread is what lets a drain/preempt make progress. The lease handle itself is not internally synchronized: poll from the thread that holds the lease.

fn bool expired() const noexcept source#

Asked to yield?

The negation of valid().

Returns

true once the owner needs the lease back.

Complexity

O(1).

Allocation

none.

fn void on_interrupt(std::function< void()> handler) source#

Register the "what to do if the owner interrupts me" handler; fires once, in the holder's thread, the first time valid() observes the stop.

Replaces any previous handler.

Complexity

O(1).

Allocation

one callback holder (the handler std::function, moved in — nothing beyond its own state).

Parameters
handler

the callback to run when the owner asks this lease to yield.

Concurrency

the handler never fires asynchronously — only from inside a valid() call, on the thread that polls it.

fn void drop() noexcept source#
fn void steal(Lease &o) noexcept source#

Constants & variables

var T * obj_ source#

direct pointer to the object (one deref).

var std::shared_ptr< detail::Gate > gate_ source#

shared yield signal (per generation / active write).

var std::function< void()> release_ source#

tells the owner "I'm done" (fired once, in dtor).

var std::function< void()> on_interrupt_ source#

optional push handler when asked to yield.

var bool fired_ source#

has on_interrupt_ fired for the current stop?