From 310adf7ca69957703dc4b1c43f4932b26539bcc7 Mon Sep 17 00:00:00 2001 From: Alice Ryhl Date: Mon, 2 Oct 2023 15:05:48 +0200 Subject: [PATCH] rt: fix flaky test `test_disable_lifo_slot` (#6043) --- tokio/tests/rt_threaded.rs | 27 ++++++++++++++++++++++++++- 1 file changed, 26 insertions(+), 1 deletion(-) diff --git a/tokio/tests/rt_threaded.rs b/tokio/tests/rt_threaded.rs index 83df6ed480f..8a61c6ad38f 100644 --- a/tokio/tests/rt_threaded.rs +++ b/tokio/tests/rt_threaded.rs @@ -746,12 +746,34 @@ mod unstable { #[test] fn test_disable_lifo_slot() { + use std::sync::mpsc::{channel, RecvTimeoutError}; + let rt = runtime::Builder::new_multi_thread() .disable_lifo_slot() .worker_threads(2) .build() .unwrap(); + // Spawn a background thread to poke the runtime periodically. + // + // This is necessary because we may end up triggering the issue in: + // + // + // Spawning a task will wake up the second worker, which will then steal + // the task. However, the steal will fail if the task is in the LIFO + // slot, because the LIFO slot cannot be stolen. + // + // Note that this only happens rarely. Most of the time, this thread is + // not necessary. + let (kill_bg_thread, recv) = channel::<()>(); + let handle = rt.handle().clone(); + let bg_thread = std::thread::spawn(move || { + let one_sec = std::time::Duration::from_secs(1); + while recv.recv_timeout(one_sec) == Err(RecvTimeoutError::Timeout) { + handle.spawn(async {}); + } + }); + rt.block_on(async { tokio::spawn(async { // Spawn another task and block the thread until completion. If the LIFO slot @@ -760,7 +782,10 @@ mod unstable { }) .await .unwrap(); - }) + }); + + drop(kill_bg_thread); + bg_thread.join().unwrap(); } #[test]