1 #![warn(rust_2018_idioms)] 2 #![cfg(feature = "full")] 3 #![cfg(unix)] 4 #![cfg(not(miri))] // No `sigaction` on Miri. 5 6 mod support { 7 pub mod signal; 8 } 9 use support::signal::send_signal; 10 11 use tokio::runtime::Runtime; 12 use tokio::signal::unix::{signal, SignalKind}; 13 14 use std::sync::mpsc::channel; 15 use std::thread; 16 17 #[test] multi_loop()18fn multi_loop() { 19 // An "ordinary" (non-future) channel 20 let (sender, receiver) = channel(); 21 // Run multiple times, to make sure there are no race conditions 22 for _ in 0..10 { 23 // Run multiple event loops, each one in its own thread 24 let threads: Vec<_> = (0..4) 25 .map(|_| { 26 let sender = sender.clone(); 27 thread::spawn(move || { 28 let rt = rt(); 29 let _ = rt.block_on(async { 30 let mut signal = signal(SignalKind::hangup()).unwrap(); 31 sender.send(()).unwrap(); 32 signal.recv().await 33 }); 34 }) 35 }) 36 .collect(); 37 // Wait for them to declare they're ready 38 for &_ in threads.iter() { 39 receiver.recv().unwrap(); 40 } 41 // Send a signal 42 send_signal(libc::SIGHUP); 43 // Make sure the threads terminated correctly 44 for t in threads { 45 t.join().unwrap(); 46 } 47 } 48 } 49 rt() -> Runtime50fn rt() -> Runtime { 51 tokio::runtime::Builder::new_current_thread() 52 .enable_all() 53 .build() 54 .unwrap() 55 } 56