pub struct Accessor<T: 'static, D = HasSelf<T>>where
D: HasData,{ /* private fields */ }
runtime
and component-model
and component-model-async
only.Expand description
Provides scoped mutable access to store data in the context of a concurrent host task future.
This allows multiple host task futures to execute concurrently and access
the store between (but not across) await
points.
§Rationale
This structure is sort of like &mut T
plus a projection from &mut T
to
D::Data<'_>
. The problem this is solving, however, is that it does not
literally store these values. The basic problem is that when a concurrent
host future is being polled it has access to &mut T
(and the whole
Store
) but when it’s not being polled it does not have access to these
values. This reflects how the store is only ever polling one future at a
time so the store is effectively being passed between futures.
Rust’s Future
trait, however, has no means of passing a Store
temporarily between futures. The Context
type does
not have the ability to attach arbitrary information to it at this time.
This type, Accessor
, is used to bridge this expressivity gap.
The Accessor
type here represents the ability to acquire, temporarily in
a synchronous manner, the current store. The Accessor::with
function
yields an Access
which can be used to access StoreContextMut
, &mut T
, or D::Data<'_>
. Note though that Accessor::with
intentionally does
not take an async
closure as its argument, instead it’s a synchronous
closure which must complete during on run of Future::poll
. This reflects
how the store is temporarily made available while a host future is being
polled.
§Implementation
This type does not actually store &mut T
nor StoreContextMut<T>
, and
this type additionally doesn’t even have a lifetime parameter. This is
instead a representation of proof of the ability to acquire these while a
future is being polled. Wasmtime will, when it polls a host future,
configure ambient state such that the Accessor
that a future closes over
will work and be able to access the store.
This has a number of implications for users such as:
- It’s intentional that
Accessor
cannot be cloned, it needs to stay within the lifetime of a single future. - A futures is expected to, however, close over an
Accessor
and keep it alive probably for the duration of the entire future. - Different host futures will be given different
Accessor
s, and that’s intentional. - The
Accessor
type isSend
andSync
irrespective ofT
which alleviates some otherwise required bounds to be written down.
§Using Accessor
in Drop
The methods on Accessor
are only expected to work in the context of
Future::poll
and are not guaranteed to work in Drop
. This is because a
host future can be dropped at any time throughout the system and Wasmtime
store context is not necessarily available at that time. It’s recommended to
not use Accessor
methods in anything connected to a Drop
implementation
as they will panic and have unintended results. If you run into this though
feel free to file an issue on the Wasmtime repository.
Implementations§
Source§impl<T, D> Accessor<T, D>where
D: HasData,
impl<T, D> Accessor<T, D>where
D: HasData,
Sourcepub fn with<R>(&self, fun: impl FnOnce(Access<'_, T, D>) -> R) -> R
pub fn with<R>(&self, fun: impl FnOnce(Access<'_, T, D>) -> R) -> R
Run the specified closure, passing it mutable access to the store.
This function is one of the main building blocks of the Accessor
type. This yields synchronous, blocking, access to store via an
Access
. The Access
implements AsContextMut
in addition to
providing the ability to access D
via Access::get
. Note that the
fun
here is given only temporary access to the store and T
/D
meaning that the return value R
here is not allowed to capture borrows
into the two. If access is needed to data within T
or D
outside of
this closure then it must be clone
d out, for example.
§Panics
This function will panic if it is call recursively with any other
accessor already in scope. For example if with
is called within fun
,
then this function will panic. It is up to the embedder to ensure that
this does not happen.
Sourcepub fn spawn(&self, task: impl AccessorTask<T, D, Result<()>>) -> AbortHandlewhere
T: 'static,
pub fn spawn(&self, task: impl AccessorTask<T, D, Result<()>>) -> AbortHandlewhere
T: 'static,
Spawn a background task which will receive an &Accessor<T, D>
and
run concurrently with any other tasks in progress for the current
instance.
This is particularly useful for host functions which return a stream
or future
such that the code to write to the write end of that
stream
or future
must run after the function returns.
The returned AbortHandle
may be used to cancel the task.
§Panics
Panics if called within a closure provided to the Accessor::with
function. This can only be called outside an active invocation of
Accessor::with
.
Trait Implementations§
Source§impl<T, D: HasData> AsAccessor for Accessor<T, D>
impl<T, D: HasData> AsAccessor for Accessor<T, D>
Source§type AccessorData = D
type AccessorData = D
D
in Accessor<T, D>
, or the projection out of
Self::Data
.Source§fn as_accessor(&self) -> &Accessor<T, D>
fn as_accessor(&self) -> &Accessor<T, D>
Auto Trait Implementations§
impl<T, D> Freeze for Accessor<T, D>
impl<T, D> RefUnwindSafe for Accessor<T, D>
impl<T, D> Send for Accessor<T, D>
impl<T, D> Sync for Accessor<T, D>
impl<T, D> Unpin for Accessor<T, D>
impl<T, D> UnwindSafe for Accessor<T, D>
Blanket Implementations§
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> 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