MCPcopy Create free account
hub / github.com/bytecodealliance/wasmtime / resume_separate_thread3

Function resume_separate_thread3

tests/all/async_functions.rs:560–618  ·  view source on GitHub ↗
()

Source from the content-addressed store, hash-verified

558#[tokio::test]
559#[cfg_attr(miri, ignore)]
560async fn resume_separate_thread3() {
561 let _ = env_logger::try_init();
562
563 // This test doesn't actually do anything with cross-thread polls, but
564 // instead it deals with scheduling futures at "odd" times.
565 //
566 // First we'll set up a *synchronous* call which will initialize TLS info.
567 // This call is simply to a host-defined function, but it still has the same
568 // "enter into wasm" semantics since it's just calling a trampoline. In this
569 // situation we'll set up the TLS info so it's in place while the body of
570 // the function executes...
571 let mut store = Store::new(&Engine::default(), None);
572 let f = Func::wrap(&mut store, move |mut caller: Caller<'_, _>| -> Result<()> {
573 // ... and the execution of this host-defined function (while the TLS
574 // info is initialized), will set up a recursive call into wasm. This
575 // recursive call will be done asynchronously so we can suspend it
576 // halfway through.
577 let f = async {
578 let mut store = async_store();
579 let module = Module::new(
580 store.engine(),
581 "
582 (module
583 (import \"\" \"\" (func))
584 (start 0)
585 )
586 ",
587 )
588 .unwrap();
589 let func = Func::wrap_async(&mut store, |_, _: ()| {
590 Box::new(async {
591 tokio::task::yield_now().await;
592 })
593 });
594 drop(Instance::new_async(&mut store, &module, &[func.into()]).await);
595 unreachable!()
596 };
597 let mut future = Box::pin(f);
598 let poll = future
599 .as_mut()
600 .poll(&mut Context::from_waker(Waker::noop()));
601 assert!(poll.is_pending());
602
603 // ... so at this point our call into wasm is suspended. The call into
604 // wasm will have overwritten TLS info, and we sure hope that the
605 // information is restored at this point. Note that we squirrel away the
606 // future somewhere else to get dropped later. If we were to drop it
607 // here then we would reenter the future's suspended stack to clean it
608 // up, which would do more alterations of TLS information we're not
609 // testing here.
610 *caller.data_mut() = Some(future);
611
612 // ... all in all this function will need access to the original TLS
613 // information to raise the trap. This TLS information should be
614 // restored even though the asynchronous execution is suspended.
615 bail!("")
616 });
617 assert!(f.call(&mut store, &[], &mut []).is_err());

Callers

nothing calls this directly

Calls 9

yield_nowFunction · 0.85
async_storeFunction · 0.70
newFunction · 0.50
dropFunction · 0.50
unwrapMethod · 0.45
engineMethod · 0.45
pollMethod · 0.45
as_mutMethod · 0.45
data_mutMethod · 0.45

Tested by

no test coverage detected