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()18 fn 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() -> Runtime50 fn rt() -> Runtime {
51     tokio::runtime::Builder::new_current_thread()
52         .enable_all()
53         .build()
54         .unwrap()
55 }
56