mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-28 12:10:37 +00:00
signal: Update to winapi 0.3
This commit is contained in:
parent
a4895fe364
commit
4fa1b2b58c
@ -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"]
|
||||
|
19
src/lib.rs
19
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<T> = Box<Future<Item = T, Error = io::Error> + Send>;
|
||||
/// A stream whose error is `io::Error`
|
||||
pub type IoStream<T> = Box<Stream<Item = T, Error = io::Error> + 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<IoStream<()>> {
|
||||
|
||||
#[cfg(unix)]
|
||||
fn ctrl_c_imp(handle: &Handle) -> IoFuture<IoStream<()>> {
|
||||
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<Stream<Item = _, Error = _> + Send>
|
||||
}))
|
||||
}
|
||||
|
||||
#[cfg(windows)]
|
||||
fn ctrl_c_imp(handle: &Handle) -> IoFuture<IoStream<()>> {
|
||||
windows::Event::ctrl_c(handle).map(|x| x.boxed()).boxed()
|
||||
Box::new(windows::Event::ctrl_c(handle).map(|x| {
|
||||
Box::new(x) as Box<Stream<Item = _, Error = _> + Send>
|
||||
}))
|
||||
}
|
||||
}
|
||||
|
@ -378,7 +378,7 @@ impl Signal {
|
||||
})
|
||||
})();
|
||||
|
||||
future::result(result).boxed()
|
||||
Box::new(future::result(result))
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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<io::Result<Event>>),
|
||||
NewEvent(DWORD, oneshot::Sender<io::Result<Event>>),
|
||||
}
|
||||
|
||||
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> {
|
||||
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> {
|
||||
Event::new(winapi::CTRL_BREAK_EVENT, handle)
|
||||
Event::new(CTRL_BREAK_EVENT, handle)
|
||||
}
|
||||
|
||||
fn new(signum: winapi::DWORD, handle: &Handle) -> IoFuture<Event> {
|
||||
fn new(signum: DWORD, handle: &Handle) -> IoFuture<Event> {
|
||||
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
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
x
Reference in New Issue
Block a user