diff --git a/tokio/tests/rt_basic.rs b/tokio/tests/rt_basic.rs index 789c0475d..47bf2dfdc 100644 --- a/tokio/tests/rt_basic.rs +++ b/tokio/tests/rt_basic.rs @@ -181,25 +181,35 @@ fn drop_tasks_in_context() { #[cfg_attr(target_os = "wasi", ignore = "Wasi does not support panic recovery")] #[should_panic(expected = "boom")] fn wake_in_drop_after_panic() { - let (tx, rx) = oneshot::channel::<()>(); - struct WakeOnDrop(Option>); impl Drop for WakeOnDrop { fn drop(&mut self) { - self.0.take().unwrap().send(()).unwrap(); + let _ = self.0.take().unwrap().send(()); } } let rt = rt(); + let (tx1, rx1) = oneshot::channel::<()>(); + let (tx2, rx2) = oneshot::channel::<()>(); + + // Spawn two tasks. We don't know the order in which they are dropped, so we + // make both tasks identical. When the first task is dropped, we wake up the + // second task. This ensures that we trigger a wakeup on a live task while + // handling the "boom" panic, no matter the order in which the tasks are + // dropped. rt.spawn(async move { - let _wake_on_drop = WakeOnDrop(Some(tx)); - // wait forever - futures::future::pending::<()>().await; + let _wake_on_drop = WakeOnDrop(Some(tx2)); + let _ = rx1.await; + unreachable!() }); - let _join = rt.spawn(async move { rx.await }); + rt.spawn(async move { + let _wake_on_drop = WakeOnDrop(Some(tx1)); + let _ = rx2.await; + unreachable!() + }); rt.block_on(async { tokio::task::yield_now().await;