1 use crate::runtime::tests::loom_oneshot as oneshot; 2 use crate::runtime::Builder; 3 use crate::task::LocalSet; 4 5 use std::task::Poll; 6 7 /// Waking a runtime will attempt to push a task into a queue of notifications 8 /// in the runtime, however the tasks in such a queue usually have a reference 9 /// to the runtime itself. This means that if they are not properly removed at 10 /// runtime shutdown, this will cause a memory leak. 11 /// 12 /// This test verifies that waking something during shutdown of a LocalSet does 13 /// not result in tasks lingering in the queue once shutdown is complete. This 14 /// is verified using loom's leak finder. 15 #[test] 16 fn wake_during_shutdown() { 17 loom::model(|| { 18 let rt = Builder::new_current_thread().build().unwrap(); 19 let ls = LocalSet::new(); 20 21 let (send, recv) = oneshot::channel(); 22 23 ls.spawn_local(async move { 24 let mut send = Some(send); 25 26 let () = futures::future::poll_fn(|cx| { 27 if let Some(send) = send.take() { 28 send.send(cx.waker().clone()); 29 } 30 31 Poll::Pending 32 }) 33 .await; 34 }); 35 36 let handle = loom::thread::spawn(move || { 37 let waker = recv.recv(); 38 waker.wake(); 39 }); 40 41 ls.block_on(&rt, crate::task::yield_now()); 42 43 drop(ls); 44 handle.join().unwrap(); 45 drop(rt); 46 }); 47 } 48