diff --git a/tests/dropping_does_not_deregister_other_instances.rs b/tests/dropping_does_not_deregister_other_instances.rs new file mode 100644 index 000000000..c0df714e6 --- /dev/null +++ b/tests/dropping_does_not_deregister_other_instances.rs @@ -0,0 +1,45 @@ +#![cfg(unix)] + +extern crate futures; +extern crate libc; +extern crate tokio; +extern crate tokio_signal; + +use futures::stream::Stream; +use futures::Future; +use tokio_signal::unix::Signal; +use std::time::{Duration, Instant}; + +#[test] +fn dropping_signal_does_not_deregister_any_other_instances() { + // NB: Deadline requires a timer registration which is provided by + // tokio's `current_thread::Runtime`, but isn't available by just using + // tokio's default CurrentThread executor which powers `current_thread::block_on_all`. + let mut rt = tokio::runtime::current_thread::Runtime::new() + .expect("failed to init runtime"); + + // FIXME(38): there appears to be a bug with the order these are created/destroyed + // If the duplicate signal is created first and dropped, it appears that `signal` + // will starve. This ordering also appears to be OS specific... + let first_signal = rt.block_on(Signal::new(libc::SIGUSR1)) + .expect("failed to register duplicate signal"); + let second_signal = rt.block_on(Signal::new(libc::SIGUSR1)) + .expect("failed to register signal"); + let (duplicate, signal) = if cfg!(target_os = "linux") { + (second_signal, first_signal) + } else { + // macOS + (first_signal, second_signal) + }; + + drop(duplicate); + + unsafe { assert_eq!(libc::kill(libc::getpid(), libc::SIGUSR1), 0); } + + let signal_future = signal.into_future() + .map_err(|(e, _)| e); + + let deadline_time = Instant::now() + Duration::from_secs(1); + rt.block_on(tokio::timer::Deadline::new(signal_future, deadline_time)) + .expect("failed to get signal"); +}