()
| 701 | |
| 702 | #[tokio::test] |
| 703 | async fn drop_suspended_async_hook() -> Result<(), Error> { |
| 704 | struct Handler; |
| 705 | |
| 706 | #[async_trait::async_trait] |
| 707 | impl CallHookHandler<u32> for Handler { |
| 708 | async fn handle_call_event( |
| 709 | &self, |
| 710 | mut ctx: StoreContextMut<'_, u32>, |
| 711 | _ch: CallHook, |
| 712 | ) -> Result<()> { |
| 713 | let state = ctx.data_mut(); |
| 714 | assert_eq!(*state, 0); |
| 715 | *state += 1; |
| 716 | let _dec = Decrement(state); |
| 717 | |
| 718 | // Simulate some sort of event which takes a number of yields |
| 719 | for _ in 0..500 { |
| 720 | tokio::task::yield_now().await; |
| 721 | } |
| 722 | Ok(()) |
| 723 | } |
| 724 | } |
| 725 | |
| 726 | let engine = Engine::default(); |
| 727 | let mut store = Store::new(&engine, 0); |
| 728 | store.call_hook_async(Handler); |
| 729 | |
| 730 | let mut linker = Linker::new(&engine); |
| 731 | |
| 732 | // Simulate a host function that has lots of yields with an infinite loop. |
| 733 | linker.func_wrap_async("host", "f", |mut cx, _: ()| { |
| 734 | Box::new(async move { |
| 735 | let state = cx.data_mut(); |
| 736 | assert_eq!(*state, 0); |
| 737 | *state += 1; |
| 738 | let _dec = Decrement(state); |
| 739 | for _ in 0.. { |
| 740 | tokio::task::yield_now().await; |
| 741 | } |
| 742 | }) |
| 743 | })?; |
| 744 | |
| 745 | let wat = r#" |
| 746 | (module |
| 747 | (import "host" "f" (func $f)) |
| 748 | (func (export "") call $f) |
| 749 | ) |
| 750 | "#; |
| 751 | let module = Module::new(&engine, wat)?; |
| 752 | |
| 753 | let inst = linker.instantiate_async(&mut store, &module).await?; |
| 754 | assert_eq!(*store.data(), 0); |
| 755 | let export = inst |
| 756 | .get_typed_func::<(), ()>(&mut store, "") |
| 757 | .expect("export is func"); |
| 758 | |
| 759 | // First test that if we drop in the middle of an async hook that everything |
| 760 | // is alright. |
nothing calls this directly
no test coverage detected