#![cfg(feature = "support-v0_8")] use std::sync::atomic::{AtomicBool, Ordering}; use std::sync::Arc; use std::thread; use std::time::Duration; use mio_0_8::{Events, Interest, Poll, Token}; use signal_hook::consts::{SIGUSR1, SIGUSR2}; use signal_hook::low_level::raise; use signal_hook_mio::v0_8::Signals; use serial_test::serial; use libc::c_int; #[test] #[serial] fn mio_wakeup() { let mut signals = Signals::new(&[SIGUSR1]).unwrap(); let mut poll = Poll::new().unwrap(); let token = Token(0); poll.registry() .register(&mut signals, token, Interest::READABLE) .unwrap(); let mut events = Events::with_capacity(10); // The self pipe shouldn't be readable yet poll.poll(&mut events, Some(Duration::from_secs(0))) .unwrap(); assert!(events.is_empty()); raise(SIGUSR1).unwrap(); poll.poll(&mut events, Some(Duration::from_secs(10))) .unwrap(); let event = events.iter().next().unwrap(); assert!(event.is_readable()); assert_eq!(token, event.token()); let sig = signals.pending().next().unwrap(); assert_eq!(SIGUSR1, sig); // The self pipe shouldn't be readable after consuming signals poll.poll(&mut events, Some(Duration::from_secs(0))) .unwrap(); assert!(events.is_empty()); } #[test] #[serial] fn mio_multiple_signals() { let mut signals = Signals::new(&[SIGUSR1, SIGUSR2]).unwrap(); let mut poll = Poll::new().unwrap(); let token = Token(0); poll.registry() .register(&mut signals, token, Interest::READABLE) .unwrap(); let mut events = Events::with_capacity(10); raise(SIGUSR1).unwrap(); raise(SIGUSR2).unwrap(); poll.poll(&mut events, Some(Duration::from_secs(10))) .unwrap(); let event = events.iter().next().unwrap(); assert!(event.is_readable()); let sigs: Vec = signals.pending().collect(); assert_eq!(2, sigs.len()); assert!(sigs.contains(&SIGUSR1)); assert!(sigs.contains(&SIGUSR2)); // The self pipe shouldn't be completely empty after calling pending() poll.poll(&mut events, Some(Duration::from_secs(0))) .unwrap(); assert!(events.is_empty()); } #[test] #[serial] fn mio_parallel_multiple() { let mut signals = Signals::new(&[SIGUSR1]).unwrap(); let mut poll = Poll::new().unwrap(); let token = Token(0); poll.registry() .register(&mut signals, token, Interest::READABLE) .unwrap(); let mut events = Events::with_capacity(10); let thread_done = Arc::new(AtomicBool::new(false)); let done = Arc::clone(&thread_done); thread::spawn(move || { for _ in 0..10 { // Wait some time to allow main thread to poll thread::sleep(Duration::from_millis(25)); raise(SIGUSR1).unwrap(); } done.store(true, Ordering::SeqCst); // Raise a final signal so the main thread wakes up // if it already called poll. raise(SIGUSR1).unwrap(); }); while !thread_done.load(Ordering::SeqCst) { poll.poll(&mut events, Some(Duration::from_secs(10))) .unwrap(); let event = events.iter().next().unwrap(); assert!(event.is_readable()); assert_eq!(SIGUSR1, signals.pending().next().unwrap()); } }