1 #![warn(rust_2018_idioms)] 2 #![cfg(feature = "full")] 3 #![cfg(unix)] 4 5 use futures::future::join_all; 6 use std::process::Stdio; 7 use tokio::process::Command; 8 use tokio::task; 9 10 #[tokio::test] issue_42()11async fn issue_42() { 12 // We spawn a many batches of processes which should exit at roughly the 13 // same time (modulo OS scheduling delays), to make sure that consuming 14 // a readiness event for one process doesn't inadvertently starve another. 15 // We then do this many times (in parallel) in an effort to stress test the 16 // implementation to ensure there are no race conditions. 17 // See alexcrichton/tokio-process#42 for background 18 let join_handles = (0..10usize).map(|_| { 19 task::spawn(async { 20 let processes = (0..10usize).map(|i| { 21 let mut child = Command::new("echo") 22 .arg(format!("I am spawned process #{}", i)) 23 .stdin(Stdio::null()) 24 .stdout(Stdio::null()) 25 .stderr(Stdio::null()) 26 .kill_on_drop(true) 27 .spawn() 28 .unwrap(); 29 30 async move { child.wait().await } 31 }); 32 33 join_all(processes).await; 34 }) 35 }); 36 37 join_all(join_handles).await; 38 } 39