process: Bump tokio-signal version to 0.2

This commit is contained in:
Ivan Petkov 2018-05-13 14:50:42 -07:00
parent de9b401457
commit e6b044a820
No known key found for this signature in database
GPG Key ID: 0B431E9837056942
6 changed files with 88 additions and 45 deletions

View File

@ -20,6 +20,7 @@ futures = "0.1.11"
mio = "0.6.5" mio = "0.6.5"
tokio-core = "0.1.6" tokio-core = "0.1.6"
tokio-io = "0.1" tokio-io = "0.1"
tokio-reactor = "0.1"
[dev-dependencies] [dev-dependencies]
env_logger = { version = "0.4", default-features = false } env_logger = { version = "0.4", default-features = false }
@ -43,4 +44,4 @@ features = [
[target.'cfg(unix)'.dependencies] [target.'cfg(unix)'.dependencies]
libc = "0.2" libc = "0.2"
tokio-signal = "0.1" tokio-signal = "0.2"

View File

@ -30,7 +30,7 @@
//! // Use the standard library's `Command` type to build a process and //! // Use the standard library's `Command` type to build a process and
//! // then execute it via the `CommandExt` trait. //! // then execute it via the `CommandExt` trait.
//! let child = Command::new("echo").arg("hello").arg("world") //! let child = Command::new("echo").arg("hello").arg("world")
//! .spawn_async(&core.handle()); //! .spawn_async_with_handle(core.handle().new_tokio_handle());
//! //!
//! // Make sure our child succeeded in spawning //! // Make sure our child succeeded in spawning
//! let child = child.expect("failed to spawn"); //! let child = child.expect("failed to spawn");
@ -62,7 +62,7 @@
//! // Like above, but use `output_async` which returns a future instead of //! // Like above, but use `output_async` which returns a future instead of
//! // immediately returning the `Child`. //! // immediately returning the `Child`.
//! let output = Command::new("echo").arg("hello").arg("world") //! let output = Command::new("echo").arg("hello").arg("world")
//! .output_async(&core.handle()); //! .output_async_with_handle(core.handle().new_tokio_handle());
//! let output = core.run(output).expect("failed to collect output"); //! let output = core.run(output).expect("failed to collect output");
//! //!
//! assert!(output.status.success()); //! assert!(output.status.success());
@ -100,7 +100,7 @@
//! let mut core = Core::new().unwrap(); //! let mut core = Core::new().unwrap();
//! let mut cmd = Command::new("cat"); //! let mut cmd = Command::new("cat");
//! let mut cat = cmd.stdout(Stdio::piped()); //! let mut cat = cmd.stdout(Stdio::piped());
//! let child = cat.spawn_async(&core.handle()).unwrap(); //! let child = cat.spawn_async_with_handle(core.handle().new_tokio_handle()).unwrap();
//! core.run(print_lines(child)).unwrap(); //! core.run(print_lines(child)).unwrap();
//! } //! }
//! ``` //! ```
@ -122,6 +122,7 @@
extern crate futures; extern crate futures;
extern crate tokio_core; extern crate tokio_core;
extern crate tokio_io; extern crate tokio_io;
extern crate tokio_reactor;
extern crate mio; extern crate mio;
use std::io::{self, Read, Write}; use std::io::{self, Read, Write};
@ -130,9 +131,9 @@ use std::process::{self, ExitStatus, Output, Stdio};
use futures::{Future, Poll, IntoFuture}; use futures::{Future, Poll, IntoFuture};
use futures::future::{Either, ok}; use futures::future::{Either, ok};
use std::fmt; use std::fmt;
use tokio_core::reactor::Handle;
use tokio_io::io::{read_to_end}; use tokio_io::io::{read_to_end};
use tokio_io::{AsyncWrite, AsyncRead, IoFuture}; use tokio_io::{AsyncWrite, AsyncRead, IoFuture};
use tokio_reactor::Handle;
#[path = "unix.rs"] #[path = "unix.rs"]
#[cfg(unix)] #[cfg(unix)]
@ -154,6 +155,22 @@ mod imp;
/// I/O handles created from this crate are all asynchronous as well (differing /// I/O handles created from this crate are all asynchronous as well (differing
/// from their `std` counterparts). /// from their `std` counterparts).
pub trait CommandExt { pub trait CommandExt {
/// Executes the command as a child process, returning a handle to it.
///
/// By default, stdin, stdout and stderr are inherited from the parent.
///
/// This method will spawn the child process synchronously and return a
/// handle to a future-aware child process. The `Child` returned implements
/// `Future` itself to acquire the `ExitStatus` of the child, and otherwise
/// the `Child` has methods to acquire handles to the stdin, stdout, and
/// stderr streams.
///
/// All I/O this child does will be associated with the current default
/// event loop.
fn spawn_async(&mut self) -> io::Result<Child> {
self.spawn_async_with_handle(&Handle::default())
}
/// Executes the command as a child process, returning a handle to it. /// Executes the command as a child process, returning a handle to it.
/// ///
/// By default, stdin, stdout and stderr are inherited from the parent. /// By default, stdin, stdout and stderr are inherited from the parent.
@ -167,7 +184,32 @@ pub trait CommandExt {
/// The `handle` specified to this method must be a handle to a valid event /// The `handle` specified to this method must be a handle to a valid event
/// loop, and all I/O this child does will be associated with the specified /// loop, and all I/O this child does will be associated with the specified
/// event loop. /// event loop.
fn spawn_async(&mut self, handle: &Handle) -> io::Result<Child>; fn spawn_async_with_handle(&mut self, handle: &Handle) -> io::Result<Child>;
/// Executes a command as a child process, waiting for it to finish and
/// collecting its exit status.
///
/// By default, stdin, stdout and stderr are inherited from the parent.
///
/// The `StatusAsync` future returned will resolve to the `ExitStatus`
/// type in the standard library representing how the process exited. If
/// any input/output handles are set to a pipe then they will be immediately
/// closed after the child is spawned.
///
/// All I/O this child does will be associated with the current default
/// event loop.
///
/// If the `StatusAsync` future is dropped before the future resolves, then
/// the child will be killed, if it was spawned.
///
/// # Errors
///
/// This function will return an error immediately if the child process
/// cannot be spawned. Otherwise errors obtained while waiting for the child
/// are returned through the `StatusAsync` future.
fn status_async(&mut self) -> io::Result<StatusAsync> {
self.status_async_with_handle(&Handle::default())
}
/// Executes a command as a child process, waiting for it to finish and /// Executes a command as a child process, waiting for it to finish and
/// collecting its exit status. /// collecting its exit status.
@ -190,33 +232,30 @@ pub trait CommandExt {
/// This function will return an error immediately if the child process /// This function will return an error immediately if the child process
/// cannot be spawned. Otherwise errors obtained while waiting for the child /// cannot be spawned. Otherwise errors obtained while waiting for the child
/// are returned through the `StatusAsync` future. /// are returned through the `StatusAsync` future.
fn status_async(&mut self, handle: &Handle) -> io::Result<StatusAsync>; fn status_async_with_handle(&mut self, handle: &Handle) -> io::Result<StatusAsync>;
/// Executes a command as a child process, waiting for it to finish and /// Executes the command as a child process, waiting for it to finish and
/// collecting its exit status. /// collecting all of its output.
/// ///
/// By default, stdin, stdout and stderr are inherited from the parent. /// > **Note**: this method, unlike the standard library, will
/// > unconditionally configure the stdout/stderr handles to be pipes, even
/// > if they have been previously configured. If this is not desired then
/// > the `spawn_async` method should be used in combination with the
/// > `wait_with_output` method on child.
/// ///
/// The `StatusAsync` future returned will resolve to the `ExitStatus` /// This method will return a future representing the collection of the
/// type in the standard library representing how the process exited. If /// child process's stdout/stderr. The `OutputAsync` future will resolve to
/// any input/output handles are set to a pipe then they will be immediately /// the `Output` type in the standard library, containing `stdout` and
/// closed after the child is spawned. /// `stderr` as `Vec<u8>` along with an `ExitStatus` representing how the
/// process exited.
/// ///
/// The `handle` specified must be a handle to a valid event loop, and all /// All I/O this child does will be associated with the current default
/// I/O this child does will be associated with the specified event loop. /// event loop.
/// ///
/// If the `StatusAsync` future is dropped before the future resolves, then /// If the `OutputAsync` future is dropped before the future resolves, then
/// the child will be killed, if it was spawned. /// the child will be killed, if it was spawned.
/// fn output_async(&mut self) -> OutputAsync {
/// # Errors self.output_async_with_handle(&Handle::default())
///
/// This function will return an error immediately if the child process
/// cannot be spawned. Otherwise errors obtained while waiting for the child
/// are returned through the `StatusAsync2` future.
#[doc(hidden)]
#[deprecated(note = "renamed to `status_async`", since = "0.2.1")]
fn status_async2(&mut self, handle: &Handle) -> io::Result<StatusAsync> {
self.status_async(handle)
} }
/// Executes the command as a child process, waiting for it to finish and /// Executes the command as a child process, waiting for it to finish and
@ -239,12 +278,12 @@ pub trait CommandExt {
/// ///
/// If the `OutputAsync` future is dropped before the future resolves, then /// If the `OutputAsync` future is dropped before the future resolves, then
/// the child will be killed, if it was spawned. /// the child will be killed, if it was spawned.
fn output_async(&mut self, handle: &Handle) -> OutputAsync; fn output_async_with_handle(&mut self, handle: &Handle) -> OutputAsync;
} }
impl CommandExt for process::Command { impl CommandExt for process::Command {
fn spawn_async(&mut self, handle: &Handle) -> io::Result<Child> { fn spawn_async_with_handle(&mut self, handle: &Handle) -> io::Result<Child> {
let mut child = Child { let mut child = Child {
child: imp::Child::new(try!(self.spawn()), handle), child: imp::Child::new(try!(self.spawn()), handle),
stdin: None, stdin: None,
@ -264,8 +303,8 @@ impl CommandExt for process::Command {
Ok(child) Ok(child)
} }
fn status_async(&mut self, handle: &Handle) -> io::Result<StatusAsync> { fn status_async_with_handle(&mut self, handle: &Handle) -> io::Result<StatusAsync> {
self.spawn_async(handle).map(|mut child| { self.spawn_async_with_handle(handle).map(|mut child| {
// Ensure we close any stdio handles so we can't deadlock // Ensure we close any stdio handles so we can't deadlock
// waiting on the child which may be waiting to read/write // waiting on the child which may be waiting to read/write
// to a pipe we're holding. // to a pipe we're holding.
@ -279,13 +318,16 @@ impl CommandExt for process::Command {
}) })
} }
fn output_async(&mut self, handle: &Handle) -> OutputAsync { fn output_async_with_handle(&mut self, handle: &Handle) -> OutputAsync {
self.stdout(Stdio::piped()); self.stdout(Stdio::piped());
self.stderr(Stdio::piped()); self.stderr(Stdio::piped());
let inner = self.spawn_async_with_handle(handle)
.into_future()
.and_then(|c| c.wait_with_output());
OutputAsync { OutputAsync {
inner: Box::new(self.spawn_async(handle).into_future().and_then(|c| { inner: Box::new(inner),
c.wait_with_output()
})),
} }
} }
} }

View File

@ -37,7 +37,7 @@ use mio;
use self::tokio_signal::unix::Signal; use self::tokio_signal::unix::Signal;
use std::fmt; use std::fmt;
use tokio_io::IoFuture; use tokio_io::IoFuture;
use tokio_core::reactor::{Handle, PollEvented}; use tokio_reactor::{Handle, PollEvented};
#[must_use = "futures do nothing unless polled"] #[must_use = "futures do nothing unless polled"]
pub struct Child { pub struct Child {
@ -62,7 +62,7 @@ impl Child {
Child { Child {
inner: inner, inner: inner,
reaped: false, reaped: false,
sigchld: Signal::new(libc::SIGCHLD, handle).flatten_stream(), sigchld: Signal::with_handle(libc::SIGCHLD, handle).flatten_stream(),
} }
} }
@ -224,6 +224,6 @@ fn stdio<T>(option: Option<T>, handle: &Handle)
return Err(io::Error::last_os_error()) return Err(io::Error::last_os_error())
} }
} }
let io = try!(PollEvented::new(Fd(io), handle)); let io = try!(PollEvented::new_with_handle(Fd(io), handle));
Ok(Some(io)) Ok(Some(io))
} }

View File

@ -36,7 +36,7 @@ use self::winapi::um::synchapi::*;
use self::winapi::um::threadpoollegacyapiset::*; use self::winapi::um::threadpoollegacyapiset::*;
use self::winapi::um::winbase::*; use self::winapi::um::winbase::*;
use self::winapi::um::winnt::*; use self::winapi::um::winnt::*;
use tokio_core::reactor::{PollEvented, Handle}; use tokio_reactor::{Handle, PollEvented};
#[must_use = "futures do nothing unless polled"] #[must_use = "futures do nothing unless polled"]
pub struct Child { pub struct Child {
@ -182,6 +182,6 @@ fn stdio<T>(option: Option<T>, handle: &Handle)
None => return Ok(None), None => return Ok(None),
}; };
let pipe = unsafe { NamedPipe::from_raw_handle(io.into_raw_handle()) }; let pipe = unsafe { NamedPipe::from_raw_handle(io.into_raw_handle()) };
let io = try!(PollEvented::new(pipe, handle)); let io = try!(PollEvented::new_with_handle(pipe, handle));
Ok(Some(io)) Ok(Some(io))
} }

View File

@ -11,7 +11,7 @@ fn simple() {
let mut lp = Core::new().unwrap(); let mut lp = Core::new().unwrap();
let mut cmd = support::cmd("exit"); let mut cmd = support::cmd("exit");
cmd.arg("2"); cmd.arg("2");
let mut child = cmd.spawn_async(&lp.handle()).unwrap(); let mut child = cmd.spawn_async_with_handle(lp.handle().new_tokio_handle()).unwrap();
let id = child.id(); let id = child.id();
assert!(id > 0); assert!(id > 0);
let status = lp.run(&mut child).unwrap(); let status = lp.run(&mut child).unwrap();

View File

@ -85,7 +85,7 @@ fn feed_cat(mut cat: Child, n: usize) -> Box<Future<Item = ExitStatus, Error = i
/// - The child does produce EOF on stdout after the last line. /// - The child does produce EOF on stdout after the last line.
fn feed_a_lot() { fn feed_a_lot() {
let mut lp = Core::new().unwrap(); let mut lp = Core::new().unwrap();
let child = cat().spawn_async(&lp.handle()).unwrap(); let child = cat().spawn_async_with_handle(lp.handle().new_tokio_handle()).unwrap();
let status = lp.run(feed_cat(child, 10000)).unwrap(); let status = lp.run(feed_cat(child, 10000)).unwrap();
assert_eq!(status.code(), Some(0)); assert_eq!(status.code(), Some(0));
} }
@ -93,7 +93,7 @@ fn feed_a_lot() {
#[test] #[test]
fn drop_kills() { fn drop_kills() {
let mut lp = Core::new().unwrap(); let mut lp = Core::new().unwrap();
let mut child = cat().spawn_async(&lp.handle()).unwrap(); let mut child = cat().spawn_async_with_handle(lp.handle().new_tokio_handle()).unwrap();
let stdin = child.stdin().take().unwrap(); let stdin = child.stdin().take().unwrap();
let stdout = child.stdout().take().unwrap(); let stdout = child.stdout().take().unwrap();
drop(child); drop(child);
@ -107,7 +107,7 @@ fn drop_kills() {
fn wait_with_output_captures() { fn wait_with_output_captures() {
let mut core = Core::new().unwrap(); let mut core = Core::new().unwrap();
let mut child = cat().spawn_async(&core.handle()).unwrap(); let mut child = cat().spawn_async_with_handle(core.handle().new_tokio_handle()).unwrap();
let stdin = child.stdin().take().unwrap(); let stdin = child.stdin().take().unwrap();
let out = child.wait_with_output(); let out = child.wait_with_output();
@ -126,7 +126,7 @@ fn status_closes_any_pipes() {
// Cat will open a pipe between the parent and child. // Cat will open a pipe between the parent and child.
// If `status_async` doesn't ensure the handles are closed, // If `status_async` doesn't ensure the handles are closed,
// we would end up blocking forever (and time out). // we would end up blocking forever (and time out).
let child = cat().status_async(&core.handle()).unwrap(); let child = cat().status_async_with_handle(core.handle().new_tokio_handle()).unwrap();
let timeout = Timeout::new(Duration::from_secs(1), &core.handle()) let timeout = Timeout::new(Duration::from_secs(1), &core.handle())
.expect("timeout registration failed") .expect("timeout registration failed")
.map(|()| panic!("time out exceeded! did we get stuck waiting on the child?")); .map(|()| panic!("time out exceeded! did we get stuck waiting on the child?"));