mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-02 00:00:11 +02:00
signal: Run rustfmt 0.4.2
This commit is contained in:
committed by
Carl Lerche
parent
7a24ed7509
commit
2848df9b6c
+10
-6
@@ -2,7 +2,7 @@ extern crate futures;
|
|||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
extern crate tokio_signal;
|
extern crate tokio_signal;
|
||||||
|
|
||||||
use futures::{Stream, Future};
|
use futures::{Future, Stream};
|
||||||
use tokio_core::reactor::Core;
|
use tokio_core::reactor::Core;
|
||||||
|
|
||||||
/// how many signals to handle before exiting
|
/// how many signals to handle before exiting
|
||||||
@@ -26,25 +26,29 @@ fn main() {
|
|||||||
// how many Ctrl+C have we received so far?
|
// how many Ctrl+C have we received so far?
|
||||||
let mut counter = 0;
|
let mut counter = 0;
|
||||||
|
|
||||||
println!("This program is now waiting for you to press Ctrl+C {0} times.
|
println!(
|
||||||
|
"This program is now waiting for you to press Ctrl+C {0} times.
|
||||||
* If running via `cargo run --example ctrl-c`, Ctrl+C also kills it, \
|
* If running via `cargo run --example ctrl-c`, Ctrl+C also kills it, \
|
||||||
due to https://github.com/rust-lang-nursery/rustup.rs/issues/806
|
due to https://github.com/rust-lang-nursery/rustup.rs/issues/806
|
||||||
* If running the binary directly, the Ctrl+C is properly trapped.
|
* If running the binary directly, the Ctrl+C is properly trapped.
|
||||||
Terminate by repeating Ctrl+C {0} times, or ahead of time by \
|
Terminate by repeating Ctrl+C {0} times, or ahead of time by \
|
||||||
opening a second terminal and issuing `pkill -sigkil ctrl-c`",
|
opening a second terminal and issuing `pkill -sigkil ctrl-c`",
|
||||||
STOP_AFTER);
|
STOP_AFTER
|
||||||
|
);
|
||||||
|
|
||||||
// Stream::for_each is a powerful primitive provided by the Futures crate.
|
// Stream::for_each is a powerful primitive provided by the Futures crate.
|
||||||
// It turns a Stream into a Future that completes after all stream-items
|
// It turns a Stream into a Future that completes after all stream-items
|
||||||
// have been completed, or the first time the closure returns an error
|
// have been completed, or the first time the closure returns an error
|
||||||
let future = limited_stream.for_each(|()| {
|
let future = limited_stream.for_each(|()| {
|
||||||
|
|
||||||
// Note how we manipulate the counter without any fancy synchronisation.
|
// Note how we manipulate the counter without any fancy synchronisation.
|
||||||
// The borrowchecker realises there can't be any conflicts, so the closure
|
// The borrowchecker realises there can't be any conflicts, so the closure
|
||||||
// can just capture it.
|
// can just capture it.
|
||||||
counter += 1;
|
counter += 1;
|
||||||
println!("Ctrl+C received {} times! {} more before exit",
|
println!(
|
||||||
counter, STOP_AFTER-counter);
|
"Ctrl+C received {} times! {} more before exit",
|
||||||
|
counter,
|
||||||
|
STOP_AFTER - counter
|
||||||
|
);
|
||||||
|
|
||||||
// return Ok-result to continue handling the stream
|
// return Ok-result to continue handling the stream
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|||||||
@@ -4,7 +4,7 @@ extern crate futures;
|
|||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
extern crate tokio_signal;
|
extern crate tokio_signal;
|
||||||
|
|
||||||
use futures::{Stream, Future};
|
use futures::{Future, Stream};
|
||||||
use tokio_core::reactor::Core;
|
use tokio_core::reactor::Core;
|
||||||
use tokio_signal::unix::{Signal, SIGINT, SIGTERM};
|
use tokio_signal::unix::{Signal, SIGINT, SIGTERM};
|
||||||
|
|
||||||
@@ -21,9 +21,11 @@ fn main() {
|
|||||||
|
|
||||||
// Wait for a signal to arrive
|
// Wait for a signal to arrive
|
||||||
println!("Waiting for SIGINT or SIGTERM");
|
println!("Waiting for SIGINT or SIGTERM");
|
||||||
println!(" TIP: use `pkill -sigint multiple` from a second terminal \
|
println!(
|
||||||
to send a SIGINT to all processes named 'multiple' \
|
" TIP: use `pkill -sigint multiple` from a second terminal \
|
||||||
(i.e. this binary)");
|
to send a SIGINT to all processes named 'multiple' \
|
||||||
|
(i.e. this binary)"
|
||||||
|
);
|
||||||
let (item, _rest) = core.run(stream.into_future()).ok().unwrap();
|
let (item, _rest) = core.run(stream.into_future()).ok().unwrap();
|
||||||
|
|
||||||
// Figure out which signal we received
|
// Figure out which signal we received
|
||||||
@@ -35,4 +37,3 @@ fn main() {
|
|||||||
println!("received SIGTERM");
|
println!("received SIGTERM");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -2,9 +2,9 @@ extern crate futures;
|
|||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
extern crate tokio_signal;
|
extern crate tokio_signal;
|
||||||
|
|
||||||
use futures::{Stream, Future};
|
use futures::{Future, Stream};
|
||||||
use tokio_core::reactor::Core;
|
use tokio_core::reactor::Core;
|
||||||
use tokio_signal::unix::{Signal,SIGHUP};
|
use tokio_signal::unix::{Signal, SIGHUP};
|
||||||
|
|
||||||
fn main() {
|
fn main() {
|
||||||
// set up a Tokio event loop
|
// set up a Tokio event loop
|
||||||
@@ -14,16 +14,21 @@ fn main() {
|
|||||||
let stream = Signal::new(SIGHUP, &core.handle()).flatten_stream();
|
let stream = Signal::new(SIGHUP, &core.handle()).flatten_stream();
|
||||||
|
|
||||||
println!("Waiting for SIGHUPS (Ctrl+C to quit)");
|
println!("Waiting for SIGHUPS (Ctrl+C to quit)");
|
||||||
println!(" TIP: use `pkill -sighup sighup-example` from a second terminal \
|
println!(
|
||||||
to send a SIGHUP to all processes named 'sighup-example' \
|
" TIP: use `pkill -sighup sighup-example` from a second terminal \
|
||||||
(i.e. this binary)");
|
to send a SIGHUP to all processes named 'sighup-example' \
|
||||||
|
(i.e. this binary)"
|
||||||
|
);
|
||||||
|
|
||||||
// for_each is a powerful primitive provided by the Futures crate
|
// for_each is a powerful primitive provided by the Futures crate
|
||||||
// it turns a Stream into a Future that completes after all stream-items
|
// it turns a Stream into a Future that completes after all stream-items
|
||||||
// have been completed.
|
// have been completed.
|
||||||
let future = stream.for_each(|the_signal| {
|
let future = stream.for_each(|the_signal| {
|
||||||
println!("*Got signal {:#x}* I should probably reload my config \
|
println!(
|
||||||
or something", the_signal);
|
"*Got signal {:#x}* I should probably reload my config \
|
||||||
|
or something",
|
||||||
|
the_signal
|
||||||
|
);
|
||||||
Ok(())
|
Ok(())
|
||||||
});
|
});
|
||||||
|
|
||||||
|
|||||||
+9
-7
@@ -84,8 +84,8 @@ extern crate tokio_io;
|
|||||||
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
use futures::stream::Stream;
|
use futures::stream::Stream;
|
||||||
|
use futures::Future;
|
||||||
use tokio_core::reactor::Handle;
|
use tokio_core::reactor::Handle;
|
||||||
|
|
||||||
pub mod unix;
|
pub mod unix;
|
||||||
@@ -113,15 +113,17 @@ 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<()>> {
|
||||||
Box::new(unix::Signal::new(unix::libc::SIGINT, handle).map(|x| {
|
Box::new(
|
||||||
Box::new(x.map(|_| ())) as Box<Stream<Item = _, Error = _> + Send>
|
unix::Signal::new(unix::libc::SIGINT, handle)
|
||||||
}))
|
.map(|x| Box::new(x.map(|_| ())) as Box<Stream<Item = _, Error = _> + Send>),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
fn ctrl_c_imp(handle: &Handle) -> IoFuture<IoStream<()>> {
|
fn ctrl_c_imp(handle: &Handle) -> IoFuture<IoStream<()>> {
|
||||||
Box::new(windows::Event::ctrl_c(handle).map(|x| {
|
Box::new(
|
||||||
Box::new(x) as Box<Stream<Item = _, Error = _> + Send>
|
windows::Event::ctrl_c(handle)
|
||||||
}))
|
.map(|x| Box::new(x) as Box<Stream<Item = _, Error = _> + Send>),
|
||||||
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+41
-32
@@ -11,27 +11,27 @@ extern crate mio_uds;
|
|||||||
|
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::collections::HashSet;
|
use std::collections::HashSet;
|
||||||
use std::io::prelude::*;
|
|
||||||
use std::io;
|
use std::io;
|
||||||
|
use std::io::prelude::*;
|
||||||
use std::mem;
|
use std::mem;
|
||||||
use std::os::unix::prelude::*;
|
use std::os::unix::prelude::*;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Mutex, Once, ONCE_INIT};
|
use std::sync::{Mutex, Once, ONCE_INIT};
|
||||||
|
|
||||||
use futures::future;
|
|
||||||
use futures::sync::mpsc::{Receiver, Sender, channel};
|
|
||||||
use futures::{Async, AsyncSink, Future};
|
|
||||||
use futures::{Sink, Stream, Poll};
|
|
||||||
use self::libc::c_int;
|
use self::libc::c_int;
|
||||||
use self::mio::Poll as MioPoll;
|
|
||||||
use self::mio::unix::EventedFd;
|
use self::mio::unix::EventedFd;
|
||||||
use self::mio::{Evented, Token, Ready, PollOpt};
|
use self::mio::Poll as MioPoll;
|
||||||
|
use self::mio::{Evented, PollOpt, Ready, Token};
|
||||||
use self::mio_uds::UnixStream;
|
use self::mio_uds::UnixStream;
|
||||||
|
use futures::future;
|
||||||
|
use futures::sync::mpsc::{channel, Receiver, Sender};
|
||||||
|
use futures::{Async, AsyncSink, Future};
|
||||||
|
use futures::{Poll, Sink, Stream};
|
||||||
|
use tokio_core::reactor::{CoreId, Handle, PollEvented};
|
||||||
use tokio_io::IoFuture;
|
use tokio_io::IoFuture;
|
||||||
use tokio_core::reactor::{Handle, CoreId, PollEvented};
|
|
||||||
|
|
||||||
pub use self::libc::{SIGINT, SIGTERM, SIGUSR1, SIGUSR2};
|
pub use self::libc::{SIGUSR1, SIGUSR2, SIGINT, SIGTERM};
|
||||||
pub use self::libc::{SIGHUP, SIGQUIT, SIGPIPE, SIGALRM, SIGTRAP};
|
pub use self::libc::{SIGALRM, SIGHUP, SIGPIPE, SIGQUIT, SIGTRAP};
|
||||||
|
|
||||||
// Number of different unix signals
|
// Number of different unix signals
|
||||||
const SIGNUM: usize = 32;
|
const SIGNUM: usize = 32;
|
||||||
@@ -95,11 +95,9 @@ fn globals() -> &'static Globals {
|
|||||||
/// Those two operations shoudl both be async-signal safe. After that's done we
|
/// Those two operations shoudl both be async-signal safe. After that's done we
|
||||||
/// just try to call a previous signal handler, if any, to be "good denizens of
|
/// just try to call a previous signal handler, if any, to be "good denizens of
|
||||||
/// the internet"
|
/// the internet"
|
||||||
extern fn handler(signum: c_int,
|
extern "C" fn handler(signum: c_int, info: *mut libc::siginfo_t, ptr: *mut libc::c_void) {
|
||||||
info: *mut libc::siginfo_t,
|
type FnSigaction = extern "C" fn(c_int, *mut libc::siginfo_t, *mut libc::c_void);
|
||||||
ptr: *mut libc::c_void) {
|
type FnHandler = extern "C" fn(c_int);
|
||||||
type FnSigaction = extern fn(c_int, *mut libc::siginfo_t, *mut libc::c_void);
|
|
||||||
type FnHandler = extern fn(c_int);
|
|
||||||
unsafe {
|
unsafe {
|
||||||
let slot = match (*GLOBALS).signals.get(signum as usize) {
|
let slot = match (*GLOBALS).signals.get(signum as usize) {
|
||||||
Some(slot) => slot,
|
Some(slot) => slot,
|
||||||
@@ -113,7 +111,7 @@ extern fn handler(signum: c_int,
|
|||||||
|
|
||||||
let fnptr = (*slot.prev.get()).sa_sigaction;
|
let fnptr = (*slot.prev.get()).sa_sigaction;
|
||||||
if fnptr == 0 || fnptr == libc::SIG_DFL || fnptr == libc::SIG_IGN {
|
if fnptr == 0 || fnptr == libc::SIG_DFL || fnptr == libc::SIG_IGN {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
if (*slot.prev.get()).sa_flags & libc::SA_SIGINFO == 0 {
|
if (*slot.prev.get()).sa_flags & libc::SA_SIGINFO == 0 {
|
||||||
let action = mem::transmute::<usize, FnHandler>(fnptr);
|
let action = mem::transmute::<usize, FnHandler>(fnptr);
|
||||||
@@ -133,22 +131,17 @@ extern fn handler(signum: c_int,
|
|||||||
fn signal_enable(signal: c_int) -> io::Result<()> {
|
fn signal_enable(signal: c_int) -> io::Result<()> {
|
||||||
let siginfo = match globals().signals.get(signal as usize) {
|
let siginfo = match globals().signals.get(signal as usize) {
|
||||||
Some(slot) => slot,
|
Some(slot) => slot,
|
||||||
None => {
|
None => return Err(io::Error::new(io::ErrorKind::Other, "signal too large")),
|
||||||
return Err(io::Error::new(io::ErrorKind::Other, "signal too large"))
|
|
||||||
}
|
|
||||||
};
|
};
|
||||||
unsafe {
|
unsafe {
|
||||||
#[cfg(target_os = "android")]
|
#[cfg(target_os = "android")]
|
||||||
fn flags() -> libc::c_ulong {
|
fn flags() -> libc::c_ulong {
|
||||||
(libc::SA_RESTART as libc::c_ulong) |
|
(libc::SA_RESTART as libc::c_ulong) | libc::SA_SIGINFO
|
||||||
libc::SA_SIGINFO |
|
| (libc::SA_NOCLDSTOP as libc::c_ulong)
|
||||||
(libc::SA_NOCLDSTOP as libc::c_ulong)
|
|
||||||
}
|
}
|
||||||
#[cfg(not(target_os = "android"))]
|
#[cfg(not(target_os = "android"))]
|
||||||
fn flags() -> c_int {
|
fn flags() -> c_int {
|
||||||
libc::SA_RESTART |
|
libc::SA_RESTART | libc::SA_SIGINFO | libc::SA_NOCLDSTOP
|
||||||
libc::SA_SIGINFO |
|
|
||||||
libc::SA_NOCLDSTOP
|
|
||||||
}
|
}
|
||||||
let mut err = None;
|
let mut err = None;
|
||||||
siginfo.init.call_once(|| {
|
siginfo.init.call_once(|| {
|
||||||
@@ -162,13 +155,15 @@ fn signal_enable(signal: c_int) -> io::Result<()> {
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
if let Some(err) = err {
|
if let Some(err) = err {
|
||||||
return Err(err)
|
return Err(err);
|
||||||
}
|
}
|
||||||
if *siginfo.initialized.get() {
|
if *siginfo.initialized.get() {
|
||||||
Ok(())
|
Ok(())
|
||||||
} else {
|
} else {
|
||||||
Err(io::Error::new(io::ErrorKind::Other,
|
Err(io::Error::new(
|
||||||
"failed to register signal handler"))
|
io::ErrorKind::Other,
|
||||||
|
"failed to register signal handler",
|
||||||
|
))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -182,7 +177,13 @@ fn signal_enable(signal: c_int) -> io::Result<()> {
|
|||||||
struct EventedReceiver;
|
struct EventedReceiver;
|
||||||
|
|
||||||
impl Evented for EventedReceiver {
|
impl Evented for EventedReceiver {
|
||||||
fn register(&self, poll: &MioPoll, token: Token, events: Ready, opts: PollOpt) -> io::Result<()> {
|
fn register(
|
||||||
|
&self,
|
||||||
|
poll: &MioPoll,
|
||||||
|
token: Token,
|
||||||
|
events: Ready,
|
||||||
|
opts: PollOpt,
|
||||||
|
) -> io::Result<()> {
|
||||||
let fd = globals().receiver.as_raw_fd();
|
let fd = globals().receiver.as_raw_fd();
|
||||||
match EventedFd(&fd).register(poll, token, events, opts) {
|
match EventedFd(&fd).register(poll, token, events, opts) {
|
||||||
Ok(()) => Ok(()),
|
Ok(()) => Ok(()),
|
||||||
@@ -191,7 +192,13 @@ impl Evented for EventedReceiver {
|
|||||||
Err(e) => Err(e),
|
Err(e) => Err(e),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn reregister(&self, poll: &MioPoll, token: Token, events: Ready, opts: PollOpt) -> io::Result<()> {
|
fn reregister(
|
||||||
|
&self,
|
||||||
|
poll: &MioPoll,
|
||||||
|
token: Token,
|
||||||
|
events: Ready,
|
||||||
|
opts: PollOpt,
|
||||||
|
) -> io::Result<()> {
|
||||||
let fd = globals().receiver.as_raw_fd();
|
let fd = globals().receiver.as_raw_fd();
|
||||||
EventedFd(&fd).reregister(poll, token, events, opts)
|
EventedFd(&fd).reregister(poll, token, events, opts)
|
||||||
}
|
}
|
||||||
@@ -270,7 +277,7 @@ impl Driver {
|
|||||||
for (sig, slot) in globals().signals.iter().enumerate() {
|
for (sig, slot) in globals().signals.iter().enumerate() {
|
||||||
// Any signal of this kind arrived since we checked last?
|
// Any signal of this kind arrived since we checked last?
|
||||||
if !slot.pending.swap(false, Ordering::SeqCst) {
|
if !slot.pending.swap(false, Ordering::SeqCst) {
|
||||||
continue
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
let signum = sig as c_int;
|
let signum = sig as c_int;
|
||||||
@@ -289,7 +296,9 @@ impl Driver {
|
|||||||
match recipients[i].start_send(signum) {
|
match recipients[i].start_send(signum) {
|
||||||
Ok(AsyncSink::Ready) => {}
|
Ok(AsyncSink::Ready) => {}
|
||||||
Ok(AsyncSink::NotReady(_)) => {}
|
Ok(AsyncSink::NotReady(_)) => {}
|
||||||
Err(_) => { recipients.swap_remove(i); }
|
Err(_) => {
|
||||||
|
recipients.swap_remove(i);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+71
-44
@@ -15,14 +15,14 @@ use std::io;
|
|||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::{Once, ONCE_INIT};
|
use std::sync::{Once, ONCE_INIT};
|
||||||
|
|
||||||
|
use self::winapi::shared::minwindef::*;
|
||||||
|
use self::winapi::um::wincon::*;
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use futures::stream::Fuse;
|
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::{Async, Future, IntoFuture, Poll, Stream};
|
||||||
use tokio_core::reactor::{PollEvented, Handle};
|
use tokio_core::reactor::{Handle, PollEvented};
|
||||||
use self::winapi::shared::minwindef::*;
|
|
||||||
use self::winapi::um::wincon::*;
|
|
||||||
|
|
||||||
use IoFuture;
|
use IoFuture;
|
||||||
|
|
||||||
@@ -103,11 +103,11 @@ impl Event {
|
|||||||
let new_signal = future::lazy(move || {
|
let new_signal = future::lazy(move || {
|
||||||
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().unbounded_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 {
|
||||||
@@ -123,28 +123,38 @@ impl Stream for Event {
|
|||||||
|
|
||||||
fn poll(&mut self) -> Poll<Option<()>, io::Error> {
|
fn poll(&mut self) -> Poll<Option<()>, io::Error> {
|
||||||
if !self.reg.poll_read().is_ready() {
|
if !self.reg.poll_read().is_ready() {
|
||||||
return Ok(Async::NotReady)
|
return Ok(Async::NotReady);
|
||||||
}
|
}
|
||||||
self.reg.need_read();
|
self.reg.need_read();
|
||||||
self.reg.get_ref()
|
self.reg
|
||||||
.inner.borrow()
|
.get_ref()
|
||||||
.as_ref().unwrap().1
|
.inner
|
||||||
.set_readiness(mio::Ready::empty())
|
.borrow()
|
||||||
.expect("failed to set readiness");
|
.as_ref()
|
||||||
|
.unwrap()
|
||||||
|
.1
|
||||||
|
.set_readiness(mio::Ready::empty())
|
||||||
|
.expect("failed to set readiness");
|
||||||
Ok(Async::Ready(Some(())))
|
Ok(Async::Ready(Some(())))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn global_init(handle: &Handle) -> io::Result<()> {
|
fn global_init(handle: &Handle) -> io::Result<()> {
|
||||||
let (tx, rx) = mpsc::unbounded();
|
let (tx, rx) = mpsc::unbounded();
|
||||||
let reg = MyRegistration { inner: RefCell::new(None) };
|
let reg = MyRegistration {
|
||||||
|
inner: RefCell::new(None),
|
||||||
|
};
|
||||||
let reg = try!(PollEvented::new(reg, handle));
|
let reg = try!(PollEvented::new(reg, handle));
|
||||||
let ready = reg.get_ref().inner.borrow().as_ref().unwrap().1.clone();
|
let ready = reg.get_ref().inner.borrow().as_ref().unwrap().1.clone();
|
||||||
unsafe {
|
unsafe {
|
||||||
let state = Box::new(GlobalState {
|
let state = Box::new(GlobalState {
|
||||||
ready: ready,
|
ready: ready,
|
||||||
ctrl_c: GlobalEventState { ready: AtomicBool::new(false) },
|
ctrl_c: GlobalEventState {
|
||||||
ctrl_break: GlobalEventState { ready: AtomicBool::new(false) },
|
ready: AtomicBool::new(false),
|
||||||
|
},
|
||||||
|
ctrl_break: GlobalEventState {
|
||||||
|
ready: AtomicBool::new(false),
|
||||||
|
},
|
||||||
tx: tx,
|
tx: tx,
|
||||||
});
|
});
|
||||||
GLOBAL_STATE = Box::into_raw(state);
|
GLOBAL_STATE = Box::into_raw(state);
|
||||||
@@ -153,7 +163,7 @@ fn global_init(handle: &Handle) -> io::Result<()> {
|
|||||||
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 _;
|
||||||
return Err(io::Error::last_os_error())
|
return Err(io::Error::last_os_error());
|
||||||
}
|
}
|
||||||
|
|
||||||
handle.spawn(DriverTask {
|
handle.spawn(DriverTask {
|
||||||
@@ -184,12 +194,12 @@ impl Future for DriverTask {
|
|||||||
|
|
||||||
impl DriverTask {
|
impl DriverTask {
|
||||||
fn check_event_drops(&mut self) {
|
fn check_event_drops(&mut self) {
|
||||||
self.ctrl_c.tasks.retain(|task| {
|
self.ctrl_c
|
||||||
!task.0.borrow_mut().poll().is_err()
|
.tasks
|
||||||
});
|
.retain(|task| !task.0.borrow_mut().poll().is_err());
|
||||||
self.ctrl_break.tasks.retain(|task| {
|
self.ctrl_break
|
||||||
!task.0.borrow_mut().poll().is_err()
|
.tasks
|
||||||
});
|
.retain(|task| !task.0.borrow_mut().poll().is_err());
|
||||||
}
|
}
|
||||||
|
|
||||||
fn check_messages(&mut self) {
|
fn check_messages(&mut self) {
|
||||||
@@ -197,8 +207,7 @@ impl DriverTask {
|
|||||||
// Acquire the next message
|
// Acquire the next message
|
||||||
let message = match self.rx.poll().unwrap() {
|
let message = match self.rx.poll().unwrap() {
|
||||||
Async::Ready(Some(e)) => e,
|
Async::Ready(Some(e)) => e,
|
||||||
Async::Ready(None) |
|
Async::Ready(None) | Async::NotReady => break,
|
||||||
Async::NotReady => break,
|
|
||||||
};
|
};
|
||||||
let (sig, complete) = match message {
|
let (sig, complete) = match message {
|
||||||
Message::NewEvent(sig, complete) => (sig, complete),
|
Message::NewEvent(sig, complete) => (sig, complete),
|
||||||
@@ -212,12 +221,14 @@ impl DriverTask {
|
|||||||
|
|
||||||
// Acquire the (registration, set_readiness) pair by... assuming
|
// Acquire the (registration, set_readiness) pair by... assuming
|
||||||
// we're on the event loop (true because of the spawn above).
|
// we're on the event loop (true because of the spawn above).
|
||||||
let reg = MyRegistration { inner: RefCell::new(None) };
|
let reg = MyRegistration {
|
||||||
|
inner: RefCell::new(None),
|
||||||
|
};
|
||||||
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) => {
|
||||||
drop(complete.send(Err(e)));
|
drop(complete.send(Err(e)));
|
||||||
continue
|
continue;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -235,18 +246,30 @@ impl DriverTask {
|
|||||||
|
|
||||||
fn check_events(&mut self) {
|
fn check_events(&mut self) {
|
||||||
if self.reg.poll_read().is_not_ready() {
|
if self.reg.poll_read().is_not_ready() {
|
||||||
return
|
return;
|
||||||
}
|
}
|
||||||
self.reg.need_read();
|
self.reg.need_read();
|
||||||
self.reg.get_ref().inner.borrow().as_ref().unwrap()
|
self.reg
|
||||||
.1.set_readiness(mio::Ready::empty()).unwrap();
|
.get_ref()
|
||||||
|
.inner
|
||||||
|
.borrow()
|
||||||
|
.as_ref()
|
||||||
|
.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() {
|
||||||
task.1.set_readiness(mio::Ready::readable()).unwrap();
|
task.1.set_readiness(mio::Ready::readable()).unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if unsafe { (*GLOBAL_STATE).ctrl_break.ready.swap(false, Ordering::SeqCst) } {
|
if unsafe {
|
||||||
|
(*GLOBAL_STATE)
|
||||||
|
.ctrl_break
|
||||||
|
.ready
|
||||||
|
.swap(false, Ordering::SeqCst)
|
||||||
|
} {
|
||||||
for task in self.ctrl_break.tasks.iter() {
|
for task in self.ctrl_break.tasks.iter() {
|
||||||
task.1.set_readiness(mio::Ready::readable()).unwrap();
|
task.1.set_readiness(mio::Ready::readable()).unwrap();
|
||||||
}
|
}
|
||||||
@@ -258,7 +281,7 @@ unsafe extern "system" fn handler(ty: DWORD) -> BOOL {
|
|||||||
let event = match ty {
|
let event = match ty {
|
||||||
CTRL_C_EVENT => &(*GLOBAL_STATE).ctrl_c,
|
CTRL_C_EVENT => &(*GLOBAL_STATE).ctrl_c,
|
||||||
CTRL_BREAK_EVENT => &(*GLOBAL_STATE).ctrl_break,
|
CTRL_BREAK_EVENT => &(*GLOBAL_STATE).ctrl_break,
|
||||||
_ => return FALSE
|
_ => return FALSE,
|
||||||
};
|
};
|
||||||
if event.ready.swap(true, Ordering::SeqCst) {
|
if event.ready.swap(true, Ordering::SeqCst) {
|
||||||
FALSE
|
FALSE
|
||||||
@@ -276,21 +299,25 @@ struct MyRegistration {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl mio::Evented for MyRegistration {
|
impl mio::Evented for MyRegistration {
|
||||||
fn register(&self,
|
fn register(
|
||||||
poll: &mio::Poll,
|
&self,
|
||||||
token: mio::Token,
|
poll: &mio::Poll,
|
||||||
events: mio::Ready,
|
token: mio::Token,
|
||||||
opts: mio::PollOpt) -> io::Result<()> {
|
events: mio::Ready,
|
||||||
|
opts: mio::PollOpt,
|
||||||
|
) -> io::Result<()> {
|
||||||
let reg = mio::Registration::new(poll, token, events, opts);
|
let reg = mio::Registration::new(poll, token, events, opts);
|
||||||
*self.inner.borrow_mut() = Some(reg);
|
*self.inner.borrow_mut() = Some(reg);
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
fn reregister(&self,
|
fn reregister(
|
||||||
_poll: &mio::Poll,
|
&self,
|
||||||
_token: mio::Token,
|
_poll: &mio::Poll,
|
||||||
_events: mio::Ready,
|
_token: mio::Token,
|
||||||
_opts: mio::PollOpt) -> io::Result<()> {
|
_events: mio::Ready,
|
||||||
|
_opts: mio::PollOpt,
|
||||||
|
) -> io::Result<()> {
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+6
-4
@@ -5,12 +5,12 @@ extern crate libc;
|
|||||||
extern crate tokio_core;
|
extern crate tokio_core;
|
||||||
extern crate tokio_signal;
|
extern crate tokio_signal;
|
||||||
|
|
||||||
use std::time::Duration;
|
|
||||||
use std::thread;
|
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
|
use std::thread;
|
||||||
|
use std::time::Duration;
|
||||||
|
|
||||||
use futures::Future;
|
|
||||||
use futures::stream::Stream;
|
use futures::stream::Stream;
|
||||||
|
use futures::Future;
|
||||||
use tokio_core::reactor::{Core, Timeout};
|
use tokio_core::reactor::{Core, Timeout};
|
||||||
use tokio_signal::unix::Signal;
|
use tokio_signal::unix::Signal;
|
||||||
|
|
||||||
@@ -34,7 +34,9 @@ fn notify_both() {
|
|||||||
unsafe {
|
unsafe {
|
||||||
assert_eq!(libc::kill(libc::getpid(), libc::SIGUSR2), 0);
|
assert_eq!(libc::kill(libc::getpid(), libc::SIGUSR2), 0);
|
||||||
}
|
}
|
||||||
lp.run(signal1.into_future().join(signal2.into_future())).ok().unwrap();
|
lp.run(signal1.into_future().join(signal2.into_future()))
|
||||||
|
.ok()
|
||||||
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
|
|||||||
Reference in New Issue
Block a user