Stream: wasmtime

Topic: ResourceLimiter: Send and async-ness changes


view this post on Zulip Notification Bot (Sep 25 2025 at 05:06):

Graydon Hoare has marked this topic as unresolved.

view this post on Zulip Graydon Hoare (Sep 25 2025 at 05:06):

no wait, that .. is no good. my access to my ResourceLimiter is through a RefCell and I can't _return_ an &mut T out of the accessor function registered on the store, because the RefCell::RefMut needs to release the borrow when we're done with it but we never get control back.

view this post on Zulip Graydon Hoare (Sep 25 2025 at 05:09):

it would be ok if the interface for working with ResourceLimiter wasn't a function on store but instead a callback from store to a closure that took a temporarily-borrowed ResourceLimiter and then returned to store so it could release a dynamic borrow..

view this post on Zulip Graydon Hoare (Sep 25 2025 at 05:15):

I guess my other option is, ugh, put the whole thing in a mutex? we hit this budget object quite often, it's already kinda terrible that it's a refcell.

view this post on Zulip Graydon Hoare (Sep 25 2025 at 05:41):

and .. that's also not possible, because the interface wants me to return &mut dyn ResourceLimiter and again, the budget object itself even if we can make _it_ an Arc<Mutex<...>> is contained as a field inside a Host that is itself an Rc<> and we _definitely_ can't make that either Send or singly owned as we'd need if we wanted to project-out one of its fields to get a singly owned &mut dyn ResourceLimiter out of it.

view this post on Zulip Graydon Hoare (Sep 25 2025 at 05:44):

I actually .. cannot think of anything we can do to make resource limiting work here, inefficiently or otherwise, with this interface as it is. it's got to either lose the Send bound, or turn into a callback interface that regains control so it can release a dynamic borrow (which I suspect will actually break the Send-ness in other ways? I'm not sure)

view this post on Zulip Graydon Hoare (Sep 25 2025 at 05:56):

basically the issue is that our T in Store<T> is not uniquely owned, nor is the budget object inside of it. and it'd involve tearing the thing apart to change that.

view this post on Zulip Alex Crichton (Sep 25 2025 at 14:20):

Ah yeah unfortunately non-Send embeddings basically just aren't well supported in Wasmtime today. We haven't figure out a great way to support it (but you're not the only one that would like us to support it!)

You're right though that it's entirely related to async, and it's related to being able to migrate a computation (future) between threads (e.g. this is a requirement to spawn a tokio future).

The only 2 solutions we know of are (1) we duplicate much of the API with Send/non-Send APIs and (2) embedders unsafely impl Send as you've outlined here. Unfortunately neither is really great and as such that's where I feel like we haven't ever figured out a great solution for this

view this post on Zulip Graydon Hoare (Sep 25 2025 at 17:03):

would you be at all amenable to the idea of changing the interface store uses (the function passed to Store::limiter) used to extract a &mut dyn ResourceLimiter? if it was possible for that to extract the &mut at the site of use via callback -- by passing a closure to the extractor-helper and having it call the callback with the &mut, then resume control -- then it could be combined with a dynamic borrow.

view this post on Zulip Alex Crichton (Sep 25 2025 at 19:52):

I'm not quite sure I follow necessarily but for me if it works it works so would be happy to change. Id caution though that the traits and interfaces here are in a fine balance right now to keep async functions producing send futures, so I suspect that changing this may be nontrivial (but am happy to be proven wrong)


Last updated: Dec 06 2025 at 06:05 UTC