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