diff --git a/Cargo.toml b/Cargo.toml index a3ac2bccc..d2718c22f 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -25,6 +25,6 @@ tokio-io = "0.1" libc = "0.2" mio-uds = "0.6" -[target.'cfg(windows)'.dependencies] -winapi = "0.2" -kernel32-sys = "0.2" +[target.'cfg(windows)'.dependencies.winapi] +version = "0.3" +features = ["minwindef", "wincon"] diff --git a/src/lib.rs b/src/lib.rs index 7b09a40ad..3927b25f9 100644 --- a/src/lib.rs +++ b/src/lib.rs @@ -78,19 +78,24 @@ #![doc(html_root_url = "https://docs.rs/tokio-signal/0.1")] #![deny(missing_docs)] -#[macro_use] extern crate futures; extern crate tokio_core; extern crate tokio_io; +use std::io; + use futures::Future; use futures::stream::Stream; use tokio_core::reactor::Handle; -use tokio_io::{IoStream, IoFuture}; pub mod unix; pub mod windows; +/// A future whose error is `io::Error` +pub type IoFuture = Box + Send>; +/// A stream whose error is `io::Error` +pub type IoStream = Box + Send>; + /// Creates a stream which receives "ctrl-c" notifications sent to a process. /// /// In general signals are handled very differently across Unix and Windows, but @@ -108,13 +113,15 @@ pub fn ctrl_c(handle: &Handle) -> IoFuture> { #[cfg(unix)] fn ctrl_c_imp(handle: &Handle) -> IoFuture> { - unix::Signal::new(unix::libc::SIGINT, handle).map(|x| { - x.map(|_| ()).boxed() - }).boxed() + Box::new(unix::Signal::new(unix::libc::SIGINT, handle).map(|x| { + Box::new(x.map(|_| ())) as Box + Send> + })) } #[cfg(windows)] fn ctrl_c_imp(handle: &Handle) -> IoFuture> { - windows::Event::ctrl_c(handle).map(|x| x.boxed()).boxed() + Box::new(windows::Event::ctrl_c(handle).map(|x| { + Box::new(x) as Box + Send> + })) } } diff --git a/src/unix.rs b/src/unix.rs index b8ae0d2a6..8ad08c4e7 100644 --- a/src/unix.rs +++ b/src/unix.rs @@ -378,7 +378,7 @@ impl Signal { }) })(); - future::result(result).boxed() + Box::new(future::result(result)) } } diff --git a/src/windows.rs b/src/windows.rs index ddb44efa3..d686c27e5 100644 --- a/src/windows.rs +++ b/src/windows.rs @@ -7,7 +7,6 @@ #![cfg(windows)] -extern crate kernel32; extern crate mio; extern crate winapi; @@ -21,8 +20,15 @@ use futures::stream::Fuse; use futures::sync::mpsc; use futures::sync::oneshot; use futures::{Future, IntoFuture, Poll, Async, Stream}; -use tokio_core::io::IoFuture; use tokio_core::reactor::{PollEvented, Handle}; +use self::winapi::shared::minwindef::*; +use self::winapi::um::wincon::*; + +use IoFuture; + +extern "system" { + fn SetConsoleCtrlHandler(HandlerRoutine: usize, Add: BOOL) -> BOOL; +} static INIT: Once = ONCE_INIT; static mut GLOBAL_STATE: *mut GlobalState = 0 as *mut _; @@ -57,7 +63,7 @@ struct GlobalEventState { } enum Message { - NewEvent(winapi::DWORD, oneshot::Sender>), + NewEvent(DWORD, oneshot::Sender>), } struct DriverTask { @@ -78,7 +84,7 @@ impl Event { /// This function will register a handler via `SetConsoleCtrlHandler` and /// deliver notifications to the returned stream. pub fn ctrl_c(handle: &Handle) -> IoFuture { - Event::new(winapi::CTRL_C_EVENT, handle) + Event::new(CTRL_C_EVENT, handle) } /// Creates a new stream listening for the `CTRL_BREAK_EVENT` events. @@ -86,10 +92,10 @@ impl Event { /// This function will register a handler via `SetConsoleCtrlHandler` and /// deliver notifications to the returned stream. pub fn ctrl_break(handle: &Handle) -> IoFuture { - Event::new(winapi::CTRL_BREAK_EVENT, handle) + Event::new(CTRL_BREAK_EVENT, handle) } - fn new(signum: winapi::DWORD, handle: &Handle) -> IoFuture { + fn new(signum: DWORD, handle: &Handle) -> IoFuture { let mut init = None; INIT.call_once(|| { init = Some(global_init(handle)); @@ -98,15 +104,15 @@ impl Event { let (tx, rx) = oneshot::channel(); let msg = Message::NewEvent(signum, tx); let res = unsafe { - (*GLOBAL_STATE).tx.clone().send(msg) + (*GLOBAL_STATE).tx.clone().unbounded_send(msg) }; res.expect("failed to request a new signal stream, did the \ first event loop go away?"); rx.then(|r| r.unwrap()) }); match init { - Some(init) => init.into_future().and_then(|()| new_signal).boxed(), - None => new_signal.boxed(), + Some(init) => Box::new(init.into_future().and_then(|()| new_signal)), + None => Box::new(new_signal), } } } @@ -123,7 +129,7 @@ impl Stream for Event { self.reg.get_ref() .inner.borrow() .as_ref().unwrap().1 - .set_readiness(mio::Ready::none()) + .set_readiness(mio::Ready::empty()) .expect("failed to set readiness"); Ok(Async::Ready(Some(()))) } @@ -143,7 +149,7 @@ fn global_init(handle: &Handle) -> io::Result<()> { }); GLOBAL_STATE = Box::into_raw(state); - let rc = kernel32::SetConsoleCtrlHandler(Some(handler), winapi::TRUE); + let rc = SetConsoleCtrlHandler(handler as usize, TRUE); if rc == 0 { Box::from_raw(GLOBAL_STATE); GLOBAL_STATE = 0 as *mut _; @@ -198,7 +204,7 @@ impl DriverTask { Message::NewEvent(sig, complete) => (sig, complete), }; - let event = if sig == winapi::CTRL_C_EVENT { + let event = if sig == CTRL_C_EVENT { &mut self.ctrl_c } else { &mut self.ctrl_break @@ -210,7 +216,7 @@ impl DriverTask { let reg = match PollEvented::new(reg, &self.handle) { Ok(reg) => reg, Err(e) => { - complete.complete(Err(e)); + drop(complete.send(Err(e))); continue } }; @@ -219,10 +225,10 @@ impl DriverTask { // the `SetReadiness` for ourselves internally. let (tx, rx) = oneshot::channel(); let ready = reg.get_ref().inner.borrow_mut().as_mut().unwrap().1.clone(); - complete.complete(Ok(Event { + drop(complete.send(Ok(Event { reg: reg, _finished: tx, - })); + }))); event.tasks.push((RefCell::new(rx), ready)); } } @@ -233,7 +239,7 @@ impl DriverTask { } self.reg.need_read(); self.reg.get_ref().inner.borrow().as_ref().unwrap() - .1.set_readiness(mio::Ready::none()).unwrap(); + .1.set_readiness(mio::Ready::empty()).unwrap(); if unsafe { (*GLOBAL_STATE).ctrl_c.ready.swap(false, Ordering::SeqCst) } { for task in self.ctrl_c.tasks.iter() { @@ -248,20 +254,20 @@ impl DriverTask { } } -unsafe extern "system" fn handler(ty: winapi::DWORD) -> winapi::BOOL { +unsafe extern "system" fn handler(ty: DWORD) -> BOOL { let event = match ty { - winapi::CTRL_C_EVENT => &(*GLOBAL_STATE).ctrl_c, - winapi::CTRL_BREAK_EVENT => &(*GLOBAL_STATE).ctrl_break, - _ => return winapi::FALSE + CTRL_C_EVENT => &(*GLOBAL_STATE).ctrl_c, + CTRL_BREAK_EVENT => &(*GLOBAL_STATE).ctrl_break, + _ => return FALSE }; if event.ready.swap(true, Ordering::SeqCst) { - winapi::FALSE + FALSE } else { drop((*GLOBAL_STATE).ready.set_readiness(mio::Ready::readable())); // TODO: this will report that we handled a CTRL_BREAK_EVENT when in // fact we may not have any streams actually created for that // event. - winapi::TRUE + TRUE } }