pub(in state::linker) struct LinkerShared {
linker_state: Arc<RwLock<LinkerState>>,
topology_coordinator: TopologyCoordinator,
dl_operation_pending: Arc<AtomicBool>,
}Expand description
Shared linkage and synchronization primitives for every super::super::Linker handle.
Cloning is cheap (Arc-backed locks and coordinators); clone when an instance-group handle
outlives a particular stack frame but must keep talking to the same dynamic-link universe.
Fields§
§linker_state: Arc<RwLock<LinkerState>>Global module tables, buses, … — see LinkerState.
topology_coordinator: TopologyCoordinatorTopologyCoordinator embedded with this linker — guards topology-changing phases.
At most one active TopologyToken may exist cluster-wide while any
topology mutation sequence is underway.
dl_operation_pending: Arc<AtomicBool>Set during LinkerShared::synchronize_link_operation so syscall paths / cooperative writers
can enter LinkerShared::do_pending_link_operations_internal.
Implementations§
Sourcepub(in state::linker) fn new(
linker_state: LinkerState,
) -> Self
pub(in state::linker) fn new( linker_state: LinkerState, ) -> Self
Wraps freshly constructed LinkerState for the owning process/module tree (initially only
the main super::super::Linker::new path).
Sourcefn assert_exactly_one_dl_bus_subscriber(ls: &LinkerState)
fn assert_exactly_one_dl_bus_subscriber(ls: &LinkerState)
Panics unless both DL buses have exactly one receiver — validates main-group bootstrap before
exclusive writes (see Self::bootstrap_exclusive_write_then).
Sourcepub(in state::linker) unsafe fn bootstrap_exclusive_write_then<R>(
&self,
f: impl FnOnce(&mut LinkerState) -> R,
) -> R
pub(in state::linker) unsafe fn bootstrap_exclusive_write_then<R>( &self, f: impl FnOnce(&mut LinkerState) -> R, ) -> R
Exclusive LinkerState write for main linker bootstrap only.
§Safety
Must run only while exactly one instance group has subscribed to both DL buses (verified
after the lock is taken — mismatch panics in release builds). Caller must respect instance-group /
linker lock ordering used in super::super::Linker::new.
Sourcepub(in state::linker) fn try_write_linker_state(
&self,
) -> Result<RwLockWriteGuard<'_, LinkerState>, TryLockError<RwLockWriteGuard<'_, LinkerState>>>
pub(in state::linker) fn try_write_linker_state( &self, ) -> Result<RwLockWriteGuard<'_, LinkerState>, TryLockError<RwLockWriteGuard<'_, LinkerState>>>
Non-blocking try_write on LinkerState.
Used sparingly where blocking would recurse into the linker (stub paths, best-effort
resolution). Prefer Self::write_linker_state for normal cooperative writes.
Sourcepub(in state::linker) fn try_read_linker_state(
&self,
) -> Result<RwLockReadGuard<'_, LinkerState>, TryLockError<RwLockReadGuard<'_, LinkerState>>>
pub(in state::linker) fn try_read_linker_state( &self, ) -> Result<RwLockReadGuard<'_, LinkerState>, TryLockError<RwLockReadGuard<'_, LinkerState>>>
Non-blocking try_read on LinkerState.
Sourcepub(in state::linker) fn write_linker_state(
&self,
group_state: &mut InstanceGroupState,
ctx: &mut FunctionEnvMut<'_, WasiEnv>,
) -> Result<RwLockWriteGuard<'_, LinkerState>, LinkError>
pub(in state::linker) fn write_linker_state( &self, group_state: &mut InstanceGroupState, ctx: &mut FunctionEnvMut<'_, WasiEnv>, ) -> Result<RwLockWriteGuard<'_, LinkerState>, LinkError>
Locks LinkerState for write using repeated try_write plus cooperative draining of
pending dynamic-link replay and LinkerStateWriteBackoff.
Prefer this over naked RwLock::write / blocking write() from instance-group linker
paths: another OS thread might hold the write lock while follower groups rendezvous at a DL
barrier waiting for this thread to run Self::do_pending_link_operations_internal.
Sourcepub(in state::linker) fn acquire_topology_token(
&self,
group_state: &mut InstanceGroupState,
store: &mut impl AsStoreMut,
env: &FunctionEnv<WasiEnv>,
) -> Result<TopologyToken, LinkError>
pub(in state::linker) fn acquire_topology_token( &self, group_state: &mut InstanceGroupState, store: &mut impl AsStoreMut, env: &FunctionEnv<WasiEnv>, ) -> Result<TopologyToken, LinkError>
TopologyCoordinator::try_acquire loop with LinkerStateWriteBackoff plus cooperative drains
of Self::do_pending_link_operations_internal.
Lock ordering: topology must be leased before taking LinkerState for write paths that
change replicated topology (spawn prepare, guarded loads, super::super::Linker::resolve_export,
etc.).
prepare_for_instance_group is the motivating case — the parent attaches no new subscribers until
the child finalizes while still holding this token handed across threads.
Sourcepub(in state::linker) fn write_linker_state_blocking_holding_topology(
&self,
topology: TopologyToken,
) -> (TopologyToken, RwLockWriteGuard<'_, LinkerState>)
pub(in state::linker) fn write_linker_state_blocking_holding_topology( &self, topology: TopologyToken, ) -> (TopologyToken, RwLockWriteGuard<'_, LinkerState>)
Blocking RwLock write once a TopologyToken is already held (spawn finalization —
e.g. super::super::Linker::create_instance_group).
Returns (token, guard) — drop the guard before token to avoid extending the write
critical section beyond topology decisions.
Sourcepub(in state::linker) fn write_linker_state_with_topology(
&self,
group_state: &mut InstanceGroupState,
ctx: &mut FunctionEnvMut<'_, WasiEnv>,
) -> Result<(TopologyToken, RwLockWriteGuard<'_, LinkerState>), LinkError>
pub(in state::linker) fn write_linker_state_with_topology( &self, group_state: &mut InstanceGroupState, ctx: &mut FunctionEnvMut<'_, WasiEnv>, ) -> Result<(TopologyToken, RwLockWriteGuard<'_, LinkerState>), LinkError>
Acquires topology (see Self::acquire_topology_token), then takes a blocking write lock via
Self::write_linker_state_blocking_holding_topology.
Use this for paths that mutate LinkerState under the topology coordinator’s single-writer
umbrella when the lease was not already taken elsewhere.
Sourcepub(in state::linker) fn synchronize_link_operation(
&self,
topology: TopologyToken,
op: DlOperation,
linker_state_write_lock: RwLockWriteGuard<'_, LinkerState>,
group_state: &mut InstanceGroupState,
wasi_process: &WasiProcess,
self_thread_id: WasiThreadId,
)
pub(in state::linker) fn synchronize_link_operation( &self, topology: TopologyToken, op: DlOperation, linker_state_write_lock: RwLockWriteGuard<'_, LinkerState>, group_state: &mut InstanceGroupState, wasi_process: &WasiProcess, self_thread_id: WasiThreadId, )
Broadcasts DlOperation op to every instance-group receiver then waits for replay.
Contracts:
topologymust already belong to this instigating flow and was leased before exclusive access to buses / tables was acquired.linker_state_write_lockguards bus broadcast invariants (try_broadcastmust succeed).- Recoverable semantic failures are surfaced by callers; panics here are always fatal — bus capacity misuse or missed rendezvous implies we cannot reconcile groups.
- Drops
topologywhen done (num_groups <= 1) or after the follower completion barrier.
Sourcepub(in state::linker) fn dl_operation_pending_load(
&self,
ordering: Ordering,
) -> bool
pub(in state::linker) fn dl_operation_pending_load( &self, ordering: Ordering, ) -> bool
Peek at the cooperative-DL handshake flag dl_operation_pending with arbitrary memory
ordering.
Prefer Ordering::SeqCst (fast = false in callers) whenever another thread waking from
Sigwakeup must reliably observe transitions; relaxed loads are intentionally lossy —
safe only when callers will retry promptly on their own syscall boundaries.
Sourcepub(in state::linker) fn do_pending_link_operations_internal(
&self,
group_state: &mut InstanceGroupState,
store: &mut impl AsStoreMut,
env: &FunctionEnv<WasiEnv>,
) -> Result<(), LinkError>
pub(in state::linker) fn do_pending_link_operations_internal( &self, group_state: &mut InstanceGroupState, store: &mut impl AsStoreMut, env: &FunctionEnv<WasiEnv>, ) -> Result<(), LinkError>
Follow half of Self::synchronize_link_operation — participates in barriers, consumes the broadcast
DlOperation, and applies op to group_state under LinkerState read access.
Intended for callers that already skipped the idle fast path (cheap load of
dl_operation_pending) yet still need deterministic rendezvous semantics.
§Panics
Missing receivers / malformed bus state panic — those are irrecoverable and indicate we lost synchronization with subscribers.
Trait Implementations§
Source§fn clone(&self) -> LinkerShared
fn clone(&self) -> LinkerShared
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read moreAuto Trait Implementations§
Blanket Implementations§
§impl<T> ArchivePointee for T
impl<T> ArchivePointee for T
§type ArchivedMetadata = ()
type ArchivedMetadata = ()
§fn pointer_metadata(
_: &<T as ArchivePointee>::ArchivedMetadata,
) -> <T as Pointee>::Metadata
fn pointer_metadata( _: &<T as ArchivePointee>::ArchivedMetadata, ) -> <T as Pointee>::Metadata
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> CloneToUninit for Twhere
T: Clone,
impl<T> CloneToUninit for Twhere
T: Clone,
§impl<T> Instrument for T
impl<T> Instrument for T
§fn instrument(self, span: Span) -> Instrumented<Self> ⓘ
fn instrument(self, span: Span) -> 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