Struct Accessor

Source
pub struct Accessor<T: 'static, D = HasSelf<T>>
where D: HasData,
{ /* private fields */ }
Available on crate features 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 Accessors, and that’s intentional.
  • The Accessor type is Send and Sync irrespective of T 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,

Source

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 cloned 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.

Source

pub fn spawn(&self, task: impl AccessorTask<T, D, Result<()>>) -> AbortHandle
where 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.

Source

pub fn instance(&self) -> Instance

Retrieve the component instance of the caller.

Trait Implementations§

Source§

impl<T, D: HasData> AsAccessor for Accessor<T, D>

Source§

type Data = T

The T in Store<T> that this accessor refers to.
Source§

type AccessorData = D

The D in Accessor<T, D>, or the projection out of Self::Data.
Source§

fn as_accessor(&self) -> &Accessor<T, D>

Returns the accessor that this is referring to.

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> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
§

impl<T> Pointable for T

§

const ALIGN: usize

The alignment of pointer.
§

type Init = T

The type for initializers.
§

unsafe fn init(init: <T as Pointable>::Init) -> usize

Initializes a with the given initializer. Read more
§

unsafe fn deref<'a>(ptr: usize) -> &'a T

Dereferences the given pointer. Read more
§

unsafe fn deref_mut<'a>(ptr: usize) -> &'a mut T

Mutably dereferences the given pointer. Read more
§

unsafe fn drop(ptr: usize)

Drops the object pointed to by the given pointer. Read more
Source§

impl<T> Same for T

Source§

type Output = T

Should always be Self
Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.