Lexical style so compiler can enforce: no sleeping (async) task can hold a RefCell.borrow_mut()?

Is there a lexical style / way to write to Rust code so that the type / borrow / lifetime checker can be used to ensure the following invariant:

no blocked (async) task is holding a RefCell::borrow_mut() ?

If you're using the multithreaded async runtime, it is enforced by default, since RefMut is neither Send nor Sync and therefore can't be held across await.

I'm on Rust / wasm, using wasm_bindgen_futures. I am compiling with target=wasm32-unknown-unknown and running it only in the Chrome browser.

I suspect the following is happening (but not sure how to verify / test this):

let x: Rc<RefCell<...>>;

  1. task1 does x.borrow_mut();
  2. task1 goes to sleep (await on something)
  3. task2 (on same wasm thread as task1) wakes up
  4. task2 does x.borrow_mut();
    PANIC!

Not sure how to verify this.

Even on a single threaded async runtime, is it possible to prevent a RefMut to be held across an await ?

Clippy has a lint for holding Ref or RefMut across await (await_holding_refcell_ref).

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.