mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-27 00:00:12 +02:00
signal: move into tokio-net (#1463)
This commit is contained in:
@@ -10,7 +10,6 @@ members = [
|
|||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"tokio-net",
|
"tokio-net",
|
||||||
"tokio-process",
|
"tokio-process",
|
||||||
"tokio-signal",
|
|
||||||
"tokio-sync",
|
"tokio-sync",
|
||||||
"tokio-test",
|
"tokio-test",
|
||||||
"tokio-timer",
|
"tokio-timer",
|
||||||
|
|||||||
+1
-1
@@ -48,11 +48,11 @@ jobs:
|
|||||||
crates:
|
crates:
|
||||||
tokio-fs: []
|
tokio-fs: []
|
||||||
tokio-net:
|
tokio-net:
|
||||||
|
- signal
|
||||||
- tcp
|
- tcp
|
||||||
- udp
|
- udp
|
||||||
- uds
|
- uds
|
||||||
tokio-process: []
|
tokio-process: []
|
||||||
tokio-signal: []
|
|
||||||
|
|
||||||
# Test crates that are NOT platform specific
|
# Test crates that are NOT platform specific
|
||||||
- template: ci/azure-test-stable.yml
|
- template: ci/azure-test-stable.yml
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ tokio-fs = { path = "tokio-fs" }
|
|||||||
tokio-io = { path = "tokio-io" }
|
tokio-io = { path = "tokio-io" }
|
||||||
tokio-macros = { path = "tokio-macros" }
|
tokio-macros = { path = "tokio-macros" }
|
||||||
tokio-net = { path = "tokio-net" }
|
tokio-net = { path = "tokio-net" }
|
||||||
tokio-signal = { path = "tokio-signal" }
|
|
||||||
tokio-sync = { path = "tokio-sync" }
|
tokio-sync = { path = "tokio-sync" }
|
||||||
tokio-timer = { path = "tokio-timer" }
|
tokio-timer = { path = "tokio-timer" }
|
||||||
tokio-tls = { path = "tokio-tls" }
|
tokio-tls = { path = "tokio-tls" }
|
||||||
|
|||||||
+14
-1
@@ -22,6 +22,13 @@ categories = ["asynchronous", "network-programming"]
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
async-traits = []
|
async-traits = []
|
||||||
|
signal = [
|
||||||
|
"futures-util-preview",
|
||||||
|
"mio-uds",
|
||||||
|
"libc",
|
||||||
|
"signal-hook-registry",
|
||||||
|
"winapi",
|
||||||
|
]
|
||||||
tcp = [
|
tcp = [
|
||||||
"bytes",
|
"bytes",
|
||||||
"futures-util-preview",
|
"futures-util-preview",
|
||||||
@@ -62,10 +69,16 @@ futures-sink-preview = { version = "=0.3.0-alpha.18", optional = true }
|
|||||||
futures-util-preview = { version = "=0.3.0-alpha.18", optional = true }
|
futures-util-preview = { version = "=0.3.0-alpha.18", optional = true }
|
||||||
iovec = { version = "0.1", optional = true }
|
iovec = { version = "0.1", optional = true }
|
||||||
|
|
||||||
# UDS
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
[target.'cfg(unix)'.dependencies]
|
||||||
|
# UDS / Signal
|
||||||
mio-uds = { version = "0.6.5", optional = true }
|
mio-uds = { version = "0.6.5", optional = true }
|
||||||
libc = { version = "0.2.42", optional = true }
|
libc = { version = "0.2.42", optional = true }
|
||||||
|
signal-hook-registry = { version = "~1", optional = true }
|
||||||
|
|
||||||
|
[target.'cfg(windows)'.dependencies.winapi]
|
||||||
|
version = "0.3"
|
||||||
|
features = ["consoleapi", "minwindef", "wincon"]
|
||||||
|
optional = true
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }
|
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }
|
||||||
|
|||||||
@@ -40,6 +40,9 @@
|
|||||||
pub mod driver;
|
pub mod driver;
|
||||||
pub mod util;
|
pub mod util;
|
||||||
|
|
||||||
|
#[cfg(feature = "signal")]
|
||||||
|
pub mod signal;
|
||||||
|
|
||||||
#[cfg(feature = "tcp")]
|
#[cfg(feature = "tcp")]
|
||||||
pub mod tcp;
|
pub mod tcp;
|
||||||
|
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
#[cfg(unix)]
|
#[cfg(unix)]
|
||||||
use crate::unix::Signal as Inner;
|
use super::unix::Signal as Inner;
|
||||||
#[cfg(windows)]
|
#[cfg(windows)]
|
||||||
use crate::windows::Event as Inner;
|
use super::windows::Event as Inner;
|
||||||
|
use crate::driver::Handle;
|
||||||
use tokio_net::driver::Handle;
|
|
||||||
|
|
||||||
use futures_core::stream::Stream;
|
use futures_core::stream::Stream;
|
||||||
use std::io;
|
use std::io;
|
||||||
@@ -1,13 +1,3 @@
|
|||||||
#![doc(html_root_url = "https://docs.rs/tokio-signal/0.3.0-alpha.1")]
|
|
||||||
#![warn(
|
|
||||||
missing_debug_implementations,
|
|
||||||
missing_docs,
|
|
||||||
rust_2018_idioms,
|
|
||||||
unreachable_pub
|
|
||||||
)]
|
|
||||||
#![cfg_attr(test, feature(async_await))]
|
|
||||||
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
|
|
||||||
|
|
||||||
//! Asynchronous signal handling for Tokio
|
//! Asynchronous signal handling for Tokio
|
||||||
//!
|
//!
|
||||||
//! This crate implements asynchronous signal handling for Tokio, an
|
//! This crate implements asynchronous signal handling for Tokio, an
|
||||||
@@ -30,6 +20,8 @@
|
|||||||
//! ```rust,no_run
|
//! ```rust,no_run
|
||||||
//! #![feature(async_await)]
|
//! #![feature(async_await)]
|
||||||
//!
|
//!
|
||||||
|
//! use tokio_net::signal;
|
||||||
|
//!
|
||||||
//! use futures_util::future;
|
//! use futures_util::future;
|
||||||
//! use futures_util::stream::StreamExt;
|
//! use futures_util::stream::StreamExt;
|
||||||
//!
|
//!
|
||||||
@@ -37,7 +29,7 @@
|
|||||||
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! // Create an infinite stream of "Ctrl+C" notifications. Each item received
|
//! // Create an infinite stream of "Ctrl+C" notifications. Each item received
|
||||||
//! // on this stream may represent multiple ctrl-c signals.
|
//! // on this stream may represent multiple ctrl-c signals.
|
||||||
//! let ctrl_c = tokio_signal::CtrlC::new()?;
|
//! let ctrl_c = signal::CtrlC::new()?;
|
||||||
//!
|
//!
|
||||||
//! // Process each ctrl-c as it comes in
|
//! // Process each ctrl-c as it comes in
|
||||||
//! let prog = ctrl_c.for_each(|_| {
|
//! let prog = ctrl_c.for_each(|_| {
|
||||||
@@ -57,15 +49,16 @@
|
|||||||
//! #![feature(async_await)]
|
//! #![feature(async_await)]
|
||||||
//! # #[cfg(unix)] {
|
//! # #[cfg(unix)] {
|
||||||
//!
|
//!
|
||||||
|
//! use tokio_net::signal::{self, unix::{Signal, SignalKind}};
|
||||||
|
//!
|
||||||
//! use futures_util::future;
|
//! use futures_util::future;
|
||||||
//! use futures_util::stream::StreamExt;
|
//! use futures_util::stream::StreamExt;
|
||||||
//! use tokio_signal::unix::{Signal, SignalKind};
|
|
||||||
//!
|
//!
|
||||||
//! #[tokio::main]
|
//! #[tokio::main]
|
||||||
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||||
//! // Create an infinite stream of "Ctrl+C" notifications. Each item received
|
//! // Create an infinite stream of "Ctrl+C" notifications. Each item received
|
||||||
//! // on this stream may represent multiple ctrl-c signals.
|
//! // on this stream may represent multiple ctrl-c signals.
|
||||||
//! let ctrl_c = tokio_signal::CtrlC::new()?;
|
//! let ctrl_c = signal::CtrlC::new()?;
|
||||||
//!
|
//!
|
||||||
//! // Process each ctrl-c as it comes in
|
//! // Process each ctrl-c as it comes in
|
||||||
//! let prog = ctrl_c.for_each(|_| {
|
//! let prog = ctrl_c.for_each(|_| {
|
||||||
@@ -87,9 +80,6 @@
|
|||||||
//! # }
|
//! # }
|
||||||
//! ```
|
//! ```
|
||||||
|
|
||||||
#[macro_use]
|
|
||||||
extern crate lazy_static;
|
|
||||||
|
|
||||||
mod ctrl_c;
|
mod ctrl_c;
|
||||||
mod registry;
|
mod registry;
|
||||||
|
|
||||||
@@ -103,4 +93,4 @@ mod os {
|
|||||||
pub mod unix;
|
pub mod unix;
|
||||||
pub mod windows;
|
pub mod windows;
|
||||||
|
|
||||||
pub use ctrl_c::CtrlC;
|
pub use self::ctrl_c::CtrlC;
|
||||||
@@ -1,11 +1,13 @@
|
|||||||
|
use super::os::{OsExtraData, OsStorage};
|
||||||
|
|
||||||
|
use tokio_sync::mpsc::Sender;
|
||||||
|
|
||||||
|
use lazy_static::lazy_static;
|
||||||
use std::ops;
|
use std::ops;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
use std::sync::atomic::{AtomicBool, Ordering};
|
use std::sync::atomic::{AtomicBool, Ordering};
|
||||||
use std::sync::Mutex;
|
use std::sync::Mutex;
|
||||||
|
|
||||||
use crate::os::{OsExtraData, OsStorage};
|
|
||||||
use tokio_sync::mpsc::Sender;
|
|
||||||
|
|
||||||
pub(crate) type EventId = usize;
|
pub(crate) type EventId = usize;
|
||||||
|
|
||||||
/// State for a specific event, whether a notification is pending delivery,
|
/// State for a specific event, whether a notification is pending delivery,
|
||||||
@@ -5,13 +5,15 @@
|
|||||||
|
|
||||||
#![cfg(unix)]
|
#![cfg(unix)]
|
||||||
|
|
||||||
pub use libc;
|
use super::registry::{globals, EventId, EventInfo, Globals, Init, Storage};
|
||||||
|
use crate::driver::Handle;
|
||||||
|
use crate::util::PollEvented;
|
||||||
|
|
||||||
use tokio_io::AsyncRead;
|
use tokio_io::AsyncRead;
|
||||||
use tokio_net::driver::Handle;
|
|
||||||
use tokio_net::util::PollEvented;
|
|
||||||
use tokio_sync::mpsc::{channel, Receiver};
|
use tokio_sync::mpsc::{channel, Receiver};
|
||||||
|
|
||||||
|
pub use libc;
|
||||||
|
|
||||||
use futures_core::stream::Stream;
|
use futures_core::stream::Stream;
|
||||||
use libc::c_int;
|
use libc::c_int;
|
||||||
use mio_uds::UnixStream;
|
use mio_uds::UnixStream;
|
||||||
@@ -22,8 +24,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
|||||||
use std::sync::Once;
|
use std::sync::Once;
|
||||||
use std::task::{Context, Poll};
|
use std::task::{Context, Poll};
|
||||||
|
|
||||||
use crate::registry::{globals, EventId, EventInfo, Globals, Init, Storage};
|
|
||||||
|
|
||||||
pub(crate) type OsStorage = Vec<SignalInfo>;
|
pub(crate) type OsStorage = Vec<SignalInfo>;
|
||||||
|
|
||||||
// Number of different unix signals
|
// Number of different unix signals
|
||||||
@@ -73,7 +73,7 @@ impl SignalKind {
|
|||||||
/// For example, this can be used for listening for platform-specific
|
/// For example, this can be used for listening for platform-specific
|
||||||
/// signals.
|
/// signals.
|
||||||
/// ```rust,no_run
|
/// ```rust,no_run
|
||||||
/// # use tokio_signal::unix::SignalKind;
|
/// # use tokio_net::signal::unix::SignalKind;
|
||||||
/// # let signum = -1;
|
/// # let signum = -1;
|
||||||
/// // let signum = libc::OS_SPECIFIC_SIGNAL;
|
/// // let signum = libc::OS_SPECIFIC_SIGNAL;
|
||||||
/// let kind = SignalKind::from_raw(signum);
|
/// let kind = SignalKind::from_raw(signum);
|
||||||
@@ -438,11 +438,6 @@ impl Stream for Signal {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
use futures_util::future::FutureExt;
|
|
||||||
use futures_util::StreamExt;
|
|
||||||
use std::time::Duration;
|
|
||||||
use tokio_sync::oneshot;
|
|
||||||
use tokio_timer::Timeout;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn signal_enable_error_on_invalid_input() {
|
fn signal_enable_error_on_invalid_input() {
|
||||||
@@ -453,25 +448,4 @@ mod tests {
|
|||||||
fn signal_enable_error_on_forbidden_input() {
|
fn signal_enable_error_on_forbidden_input() {
|
||||||
signal_enable(signal_hook_registry::FORBIDDEN[0]).unwrap_err();
|
signal_enable(signal_hook_registry::FORBIDDEN[0]).unwrap_err();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn with_timeout<F: Future>(future: F) -> impl Future<Output = F::Output> {
|
|
||||||
Timeout::new(future, Duration::from_secs(1)).map(|result| result.expect("timed out"))
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn ctrl_c() {
|
|
||||||
let ctrl_c = crate::CtrlC::new().expect("failed to init ctrl_c");
|
|
||||||
|
|
||||||
let (fire, wait) = oneshot::channel();
|
|
||||||
|
|
||||||
// NB: simulate a signal coming in by exercising our signal handler
|
|
||||||
// to avoid complications with sending SIGINT to the test process
|
|
||||||
tokio::spawn(async {
|
|
||||||
wait.await.expect("wait failed");
|
|
||||||
action(globals(), libc::SIGINT);
|
|
||||||
});
|
|
||||||
|
|
||||||
let _ = fire.send(());
|
|
||||||
let _ = with_timeout(ctrl_c.into_future()).await;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
@@ -7,9 +7,9 @@
|
|||||||
|
|
||||||
#![cfg(windows)]
|
#![cfg(windows)]
|
||||||
|
|
||||||
use crate::registry::{globals, EventId, EventInfo, Init, Storage};
|
use super::registry::{globals, EventId, EventInfo, Init, Storage};
|
||||||
|
use crate::driver::Handle;
|
||||||
|
|
||||||
use tokio_net::driver::Handle;
|
|
||||||
use tokio_sync::mpsc::{channel, Receiver};
|
use tokio_sync::mpsc::{channel, Receiver};
|
||||||
|
|
||||||
use futures_core::stream::Stream;
|
use futures_core::stream::Stream;
|
||||||
@@ -198,11 +198,13 @@ impl Stream for CtrlBreak {
|
|||||||
#[cfg(test)]
|
#[cfg(test)]
|
||||||
mod tests {
|
mod tests {
|
||||||
use super::*;
|
use super::*;
|
||||||
|
|
||||||
|
use tokio::timer::Timeout;
|
||||||
|
|
||||||
use futures_util::future::FutureExt;
|
use futures_util::future::FutureExt;
|
||||||
use futures_util::stream::StreamExt;
|
use futures_util::stream::StreamExt;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio_timer::Timeout;
|
|
||||||
|
|
||||||
fn with_timeout<F: Future>(future: F) -> impl Future<Output = F::Output> {
|
fn with_timeout<F: Future>(future: F) -> impl Future<Output = F::Output> {
|
||||||
Timeout::new(future, Duration::from_secs(1)).map(|result| result.expect("timed out"))
|
Timeout::new(future, Duration::from_secs(1)).map(|result| result.expect("timed out"))
|
||||||
@@ -210,7 +212,7 @@ mod tests {
|
|||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn ctrl_c() {
|
async fn ctrl_c() {
|
||||||
let ctrl_c = crate::CtrlC::new().expect("failed to create CtrlC");
|
let ctrl_c = crate::signal::CtrlC::new().expect("failed to create CtrlC");
|
||||||
|
|
||||||
// Windows doesn't have a good programmatic way of sending events
|
// Windows doesn't have a good programmatic way of sending events
|
||||||
// like sending signals on Unix, so we'll stub out the actual OS
|
// like sending signals on Unix, so we'll stub out the actual OS
|
||||||
@@ -1,10 +1,9 @@
|
|||||||
#![cfg(unix)]
|
#![cfg(unix)]
|
||||||
|
#![cfg(feature = "signal")]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
use libc;
|
pub mod signal_support;
|
||||||
|
use crate::signal_support::*;
|
||||||
pub mod support;
|
|
||||||
use crate::support::*;
|
|
||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn dropping_loops_does_not_cause_starvation() {
|
fn dropping_loops_does_not_cause_starvation() {
|
||||||
+3
-4
@@ -1,11 +1,10 @@
|
|||||||
#![cfg(unix)]
|
#![cfg(unix)]
|
||||||
|
#![cfg(feature = "signal")]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![feature(async_await)]
|
#![feature(async_await)]
|
||||||
|
|
||||||
use libc;
|
pub mod signal_support;
|
||||||
|
use crate::signal_support::*;
|
||||||
pub mod support;
|
|
||||||
use crate::support::*;
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn drop_then_get_a_signal() {
|
async fn drop_then_get_a_signal() {
|
||||||
+3
-4
@@ -1,11 +1,10 @@
|
|||||||
#![cfg(unix)]
|
#![cfg(unix)]
|
||||||
|
#![cfg(feature = "signal")]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![feature(async_await)]
|
#![feature(async_await)]
|
||||||
|
|
||||||
use libc;
|
pub mod signal_support;
|
||||||
|
use crate::signal_support::*;
|
||||||
pub mod support;
|
|
||||||
use crate::support::*;
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn dropping_signal_does_not_deregister_any_other_instances() {
|
async fn dropping_signal_does_not_deregister_any_other_instances() {
|
||||||
@@ -1,10 +1,10 @@
|
|||||||
#![cfg(unix)]
|
#![cfg(unix)]
|
||||||
|
#![cfg(feature = "signal")]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
pub mod support;
|
pub mod signal_support;
|
||||||
use crate::support::*;
|
use crate::signal_support::*;
|
||||||
|
|
||||||
use libc;
|
|
||||||
use std::sync::mpsc::channel;
|
use std::sync::mpsc::channel;
|
||||||
use std::thread;
|
use std::thread;
|
||||||
|
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
#![cfg(unix)]
|
#![cfg(unix)]
|
||||||
|
#![cfg(feature = "signal")]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![feature(async_await)]
|
#![feature(async_await)]
|
||||||
|
|
||||||
pub mod support;
|
pub mod signal_support;
|
||||||
use crate::support::*;
|
use crate::signal_support::*;
|
||||||
|
|
||||||
use libc;
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn notify_both() {
|
async fn notify_both() {
|
||||||
@@ -0,0 +1,37 @@
|
|||||||
|
#![cfg(unix)]
|
||||||
|
#![cfg(feature = "signal")]
|
||||||
|
#![warn(rust_2018_idioms)]
|
||||||
|
#![feature(async_await)]
|
||||||
|
|
||||||
|
pub mod signal_support;
|
||||||
|
use crate::signal_support::*;
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
async fn simple() {
|
||||||
|
let signal = Signal::new(SignalKind::user_defined1()).expect("failed to create signal");
|
||||||
|
|
||||||
|
send_signal(libc::SIGUSR1);
|
||||||
|
|
||||||
|
let _ = with_timeout(signal.into_future()).await;
|
||||||
|
}
|
||||||
|
|
||||||
|
#[tokio::test]
|
||||||
|
#[cfg(unix)]
|
||||||
|
async fn ctrl_c() {
|
||||||
|
use tokio::sync::oneshot;
|
||||||
|
use tokio_net::signal::CtrlC;
|
||||||
|
|
||||||
|
let ctrl_c = CtrlC::new().expect("failed to init ctrl_c");
|
||||||
|
|
||||||
|
let (fire, wait) = oneshot::channel();
|
||||||
|
|
||||||
|
// NB: simulate a signal coming in by exercising our signal handler
|
||||||
|
// to avoid complications with sending SIGINT to the test process
|
||||||
|
tokio::spawn(async {
|
||||||
|
wait.await.expect("wait failed");
|
||||||
|
send_signal(libc::SIGINT);
|
||||||
|
});
|
||||||
|
|
||||||
|
let _ = fire.send(());
|
||||||
|
let _ = with_timeout(ctrl_c.into_future()).await;
|
||||||
|
}
|
||||||
@@ -1,16 +1,16 @@
|
|||||||
#![cfg(unix)]
|
#![cfg(unix)]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
|
|
||||||
|
pub use tokio::runtime::current_thread::{self, Runtime as CurrentThreadRuntime};
|
||||||
|
use tokio::timer::Timeout;
|
||||||
|
pub use tokio_net::signal::unix::{Signal, SignalKind};
|
||||||
|
|
||||||
|
pub use futures_util::future;
|
||||||
use futures_util::future::FutureExt;
|
use futures_util::future::FutureExt;
|
||||||
|
pub use futures_util::stream::StreamExt;
|
||||||
use libc::{c_int, getpid, kill};
|
use libc::{c_int, getpid, kill};
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio_timer::Timeout;
|
|
||||||
|
|
||||||
pub use futures_util::future;
|
|
||||||
pub use futures_util::stream::StreamExt;
|
|
||||||
pub use tokio::runtime::current_thread::{self, Runtime as CurrentThreadRuntime};
|
|
||||||
pub use tokio_signal::unix::{Signal, SignalKind};
|
|
||||||
|
|
||||||
pub fn with_timeout<F: Future>(future: F) -> impl Future<Output = F::Output> {
|
pub fn with_timeout<F: Future>(future: F) -> impl Future<Output = F::Output> {
|
||||||
Timeout::new(future, Duration::from_secs(1)).map(Result::unwrap)
|
Timeout::new(future, Duration::from_secs(1)).map(Result::unwrap)
|
||||||
@@ -1,11 +1,10 @@
|
|||||||
#![cfg(unix)]
|
#![cfg(unix)]
|
||||||
|
#![cfg(feature = "signal")]
|
||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![feature(async_await)]
|
#![feature(async_await)]
|
||||||
|
|
||||||
pub mod support;
|
pub mod signal_support;
|
||||||
use crate::support::*;
|
use crate::signal_support::*;
|
||||||
|
|
||||||
use libc;
|
|
||||||
|
|
||||||
#[tokio::test]
|
#[tokio::test]
|
||||||
async fn twice() {
|
async fn twice() {
|
||||||
@@ -55,4 +55,4 @@ lazy_static = "1.3"
|
|||||||
libc = "0.2"
|
libc = "0.2"
|
||||||
log = "0.4"
|
log = "0.4"
|
||||||
mio = "0.6.5"
|
mio = "0.6.5"
|
||||||
tokio-signal = { version = "=0.3.0-alpha.1", path = "../tokio-signal" }
|
tokio-net = { version = "=0.2.0-alpha.1", path = "../tokio-net", features = ["signal"] }
|
||||||
|
|||||||
@@ -11,7 +11,7 @@
|
|||||||
//!
|
//!
|
||||||
//! Our best approximation here is to check *all spawned processes* for all
|
//! Our best approximation here is to check *all spawned processes* for all
|
||||||
//! SIGCHLD signals received. To do that we create a `Signal`, implemented in
|
//! SIGCHLD signals received. To do that we create a `Signal`, implemented in
|
||||||
//! the `tokio-signal` crate, which is a stream over signals being received.
|
//! the `tokio-net` crate, which is a stream over signals being received.
|
||||||
//!
|
//!
|
||||||
//! Later when we poll the process's exit status we simply check to see if a
|
//! Later when we poll the process's exit status we simply check to see if a
|
||||||
//! SIGCHLD has happened since we last checked, and while that returns "yes" we
|
//! SIGCHLD has happened since we last checked, and while that returns "yes" we
|
||||||
@@ -30,8 +30,8 @@ use super::SpawnedChild;
|
|||||||
use crate::kill::Kill;
|
use crate::kill::Kill;
|
||||||
|
|
||||||
use tokio_net::driver::Handle;
|
use tokio_net::driver::Handle;
|
||||||
|
use tokio_net::signal::unix::{Signal, SignalKind};
|
||||||
use tokio_net::util::PollEvented;
|
use tokio_net::util::PollEvented;
|
||||||
use tokio_signal::unix::{Signal, SignalKind};
|
|
||||||
|
|
||||||
use mio::event::Evented;
|
use mio::event::Evented;
|
||||||
use mio::unix::{EventedFd, UnixReady};
|
use mio::unix::{EventedFd, UnixReady};
|
||||||
|
|||||||
@@ -1,63 +0,0 @@
|
|||||||
# 0.3.0-alpha.1 (August 8, 2019)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
- Switch to `async`, `await`, and `std::future`.
|
|
||||||
- `windows::Event` has been removed in favor of `CtrlC` and
|
|
||||||
a separate `windows::CtrlBreak` struct.
|
|
||||||
- `ctrl_c{,_with_handle}` has been replaced with a `CtrlC` struct
|
|
||||||
(which can be constructed via `CtrlC::{new, with_handle}`.
|
|
||||||
- `unix::Signal` returns `()` instead of the signal number used in registration
|
|
||||||
- `unis::Signal` constructors now return a simple result rather than a lazy future
|
|
||||||
|
|
||||||
# 0.2.9
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- `windows::Event` performs internal registrations lazily, so now it can be
|
|
||||||
constructed outside of a running task
|
|
||||||
- remove usage of deprecated `Handle::current` in default `windows::Event`
|
|
||||||
constructors
|
|
||||||
|
|
||||||
# 0.2.8 (March 22, 2019)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- remove usage of deprecated `Handle::current` (#981).
|
|
||||||
|
|
||||||
## 0.2.7 - (November 21, 2018)
|
|
||||||
### Changed
|
|
||||||
* `unix::Signal` now implements `Sync`
|
|
||||||
* minimize allocations
|
|
||||||
|
|
||||||
### Fixes
|
|
||||||
* `unix::Signal` now avoids extraneous wakeups generated as a result of
|
|
||||||
dropping other instances
|
|
||||||
|
|
||||||
## 0.2.6 - (October 26, 2018)
|
|
||||||
### Changed
|
|
||||||
* Use the `signal-hook` crate for managing signal registrations
|
|
||||||
|
|
||||||
## 0.2.5 - (September 29, 2018)
|
|
||||||
### Fixes
|
|
||||||
* Fix a possible starvation when polling multiple `Signal` instances outside of
|
|
||||||
a tokio reactor (e.g. by using `Future::wait`)
|
|
||||||
|
|
||||||
## 0.2.4 - (August 25, 2018)
|
|
||||||
### Fixes
|
|
||||||
* Actually make `unix::bsd` public
|
|
||||||
|
|
||||||
## 0.2.3 - (August 25, 2018)
|
|
||||||
### Features
|
|
||||||
* Exposes `SIGINFO` on BSD-based operating systems.
|
|
||||||
|
|
||||||
## 0.2.2 - (August 14, 2018)
|
|
||||||
### Fixes
|
|
||||||
* Fix starvation of `Signal`s whenever a `Signal` instance is dropped
|
|
||||||
* Fix starvation of individual `Signal`s based on their creation order
|
|
||||||
|
|
||||||
## 0.2.1 - (May 27, 2018)
|
|
||||||
### Fixes
|
|
||||||
* Bump minimum supported version of `mio` to 0.6.14
|
|
||||||
|
|
||||||
## 0.2.0 - (May 7, 2018)
|
|
||||||
#### Features
|
|
||||||
* Uses `tokio` instead of `tokio_core`
|
|
||||||
* Supports all 33 signals on FreeBSD
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "tokio-signal"
|
|
||||||
# When releasing to crates.io:
|
|
||||||
# - Remove path dependencies
|
|
||||||
# - Update html_root_url.
|
|
||||||
# - Update doc url
|
|
||||||
# - Cargo.toml
|
|
||||||
# - Update CHANGELOG.md.
|
|
||||||
# - Create "v0.3.x" git tag.
|
|
||||||
version = "0.3.0-alpha.1"
|
|
||||||
edition = "2018"
|
|
||||||
authors = ["Tokio Contributors <[email protected]>"]
|
|
||||||
license = "MIT"
|
|
||||||
repository = "https://github.com/tokio-rs/tokio"
|
|
||||||
homepage = "https://github.com/tokio-rs/tokio"
|
|
||||||
documentation = "https://docs.rs/tokio-signal/0.3.0-alpha.1/tokio_signal"
|
|
||||||
description = """
|
|
||||||
An implementation of an asynchronous Unix signal handling backed futures.
|
|
||||||
"""
|
|
||||||
categories = ["asynchronous"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
futures-core-preview = "=0.3.0-alpha.18"
|
|
||||||
futures-util-preview = "=0.3.0-alpha.18"
|
|
||||||
lazy_static = "1"
|
|
||||||
tokio-io = { version = "=0.2.0-alpha.1", path = "../tokio-io" }
|
|
||||||
tokio-net = { version = "=0.2.0-alpha.1", path = "../tokio-net" }
|
|
||||||
tokio-sync = { version = "=0.2.0-alpha.1", path = "../tokio-sync" }
|
|
||||||
|
|
||||||
[target.'cfg(unix)'.dependencies]
|
|
||||||
libc = "0.2"
|
|
||||||
mio = "0.6.14"
|
|
||||||
mio-uds = "0.6"
|
|
||||||
signal-hook-registry = "~1"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }
|
|
||||||
tokio-timer = { version = "=0.3.0-alpha.1", path = "../tokio-timer" }
|
|
||||||
tokio-sync = { version = "=0.2.0-alpha.1", path = "../tokio-sync", features = ["async-traits"]}
|
|
||||||
|
|
||||||
[target.'cfg(windows)'.dependencies.winapi]
|
|
||||||
version = "0.3"
|
|
||||||
features = ["consoleapi", "minwindef", "wincon"]
|
|
||||||
@@ -1,25 +0,0 @@
|
|||||||
Copyright (c) 2019 Tokio contributors
|
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any
|
|
||||||
person obtaining a copy of this software and associated
|
|
||||||
documentation files (the "Software"), to deal in the
|
|
||||||
Software without restriction, including without
|
|
||||||
limitation the rights to use, copy, modify, merge,
|
|
||||||
publish, distribute, sublicense, and/or sell copies of
|
|
||||||
the Software, and to permit persons to whom the Software
|
|
||||||
is furnished to do so, subject to the following
|
|
||||||
conditions:
|
|
||||||
|
|
||||||
The above copyright notice and this permission notice
|
|
||||||
shall be included in all copies or substantial portions
|
|
||||||
of the Software.
|
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF
|
|
||||||
ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED
|
|
||||||
TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A
|
|
||||||
PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
|
|
||||||
SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY
|
|
||||||
CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
|
|
||||||
OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR
|
|
||||||
IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
|
|
||||||
DEALINGS IN THE SOFTWARE.
|
|
||||||
@@ -1,13 +0,0 @@
|
|||||||
# tokio-signal
|
|
||||||
|
|
||||||
Unix signal handling for Tokio.
|
|
||||||
|
|
||||||
## License
|
|
||||||
|
|
||||||
This project is licensed under the [MIT license](./LICENSE).
|
|
||||||
|
|
||||||
### Contribution
|
|
||||||
|
|
||||||
Unless you explicitly state otherwise, any contribution intentionally submitted
|
|
||||||
for inclusion in Tokio by you, shall be licensed as MIT, without any additional
|
|
||||||
terms or conditions.
|
|
||||||
@@ -1,42 +0,0 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
|
||||||
#![feature(async_await)]
|
|
||||||
|
|
||||||
use futures_util::stream::StreamExt;
|
|
||||||
|
|
||||||
/// how many signals to handle before exiting
|
|
||||||
const STOP_AFTER: u64 = 10;
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
// tokio_signal provides a convenience builder for Ctrl+C
|
|
||||||
// this even works cross-platform: linux and windows!
|
|
||||||
let endless_stream = tokio_signal::CtrlC::new().expect("failed to create CtrlC");
|
|
||||||
// don't keep going forever: convert the endless stream to a bounded one.
|
|
||||||
let mut limited_stream = endless_stream.take(STOP_AFTER);
|
|
||||||
|
|
||||||
// how many Ctrl+C have we received so far?
|
|
||||||
let mut counter = 0;
|
|
||||||
|
|
||||||
println!(
|
|
||||||
"This program is now waiting for you to press Ctrl+C {0} times. \
|
|
||||||
Terminate by repeating Ctrl+C {0} times, or ahead of time by opening \
|
|
||||||
a second terminal and issuing `pkill -sigkil ctrl-c`.",
|
|
||||||
STOP_AFTER
|
|
||||||
);
|
|
||||||
|
|
||||||
// Up until now, we haven't really DONE anything, just prepared
|
|
||||||
// our futures, now it's time to actually await the results!
|
|
||||||
while let Some(_) = limited_stream.next().await {
|
|
||||||
// Note how we manipulate the counter without any fancy synchronisation.
|
|
||||||
// The borrowchecker realises there can't be any conflicts, so the closure
|
|
||||||
// can just capture it.
|
|
||||||
counter += 1;
|
|
||||||
println!(
|
|
||||||
"Ctrl+C received {} times! {} more before exit",
|
|
||||||
counter,
|
|
||||||
STOP_AFTER - counter
|
|
||||||
);
|
|
||||||
}
|
|
||||||
|
|
||||||
println!("Stream ended, quiting the program.");
|
|
||||||
}
|
|
||||||
@@ -1,47 +0,0 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
|
||||||
#![feature(async_await)]
|
|
||||||
|
|
||||||
//! A small example of how to listen for two signals at the same time
|
|
||||||
|
|
||||||
// A trick to not fail build on non-unix platforms when using unix-specific features.
|
|
||||||
#[cfg(unix)]
|
|
||||||
mod platform {
|
|
||||||
use futures_util::stream::{self, StreamExt};
|
|
||||||
use tokio_signal::unix::{Signal, SignalKind};
|
|
||||||
|
|
||||||
pub async fn main() {
|
|
||||||
// Create a stream for each of the signals we'd like to handle.
|
|
||||||
let sigint = Signal::new(SignalKind::interrupt())
|
|
||||||
.unwrap()
|
|
||||||
.map(|_| "SIGINT");
|
|
||||||
let sigterm = Signal::new(SignalKind::terminate())
|
|
||||||
.unwrap()
|
|
||||||
.map(|_| "SIGTERM");
|
|
||||||
|
|
||||||
// Use the `select` combinator to merge these two streams into one
|
|
||||||
let stream = stream::select(sigint, sigterm);
|
|
||||||
|
|
||||||
// Wait for a signal to arrive
|
|
||||||
println!("Waiting for SIGINT or SIGTERM");
|
|
||||||
println!(
|
|
||||||
" TIP: use `pkill -sigint multiple` from a second terminal \
|
|
||||||
to send a SIGINT to all processes named 'multiple' \
|
|
||||||
(i.e. this binary)"
|
|
||||||
);
|
|
||||||
let (item, _rest) = stream.into_future().await;
|
|
||||||
|
|
||||||
// Figure out which signal we received
|
|
||||||
let msg = item.ok_or("received no signal").unwrap();
|
|
||||||
println!("received {}", msg);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
|
||||||
mod platform {
|
|
||||||
pub async fn main() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
platform::main().await
|
|
||||||
}
|
|
||||||
@@ -1,37 +0,0 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
|
||||||
#![feature(async_await)]
|
|
||||||
|
|
||||||
// A trick to not fail build on non-unix platforms when using unix-specific features.
|
|
||||||
#[cfg(unix)]
|
|
||||||
mod platform {
|
|
||||||
use futures_util::stream::StreamExt;
|
|
||||||
use tokio_signal::unix::{Signal, SignalKind};
|
|
||||||
|
|
||||||
pub async fn main() {
|
|
||||||
// on Unix, we can listen to whatever signal we want, in this case: SIGHUP
|
|
||||||
let mut stream = Signal::new(SignalKind::hangup()).unwrap();
|
|
||||||
|
|
||||||
println!("Waiting for SIGHUPS (Ctrl+C to quit)");
|
|
||||||
println!(
|
|
||||||
" TIP: use `pkill -sighup sighup-example` from a second terminal \
|
|
||||||
to send a SIGHUP to all processes named 'sighup-example' \
|
|
||||||
(i.e. this binary)"
|
|
||||||
);
|
|
||||||
|
|
||||||
// Up until now, we haven't really DONE anything, just prepared
|
|
||||||
// our futures, now it's time to actually await the results!
|
|
||||||
while let Some(_) = stream.next().await {
|
|
||||||
println!("*Got signal* I should probably reload my config or something");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[cfg(not(unix))]
|
|
||||||
mod platform {
|
|
||||||
pub async fn main() {}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[tokio::main]
|
|
||||||
async fn main() {
|
|
||||||
platform::main().await
|
|
||||||
}
|
|
||||||
@@ -1,17 +0,0 @@
|
|||||||
#![cfg(unix)]
|
|
||||||
#![warn(rust_2018_idioms)]
|
|
||||||
#![feature(async_await)]
|
|
||||||
|
|
||||||
pub mod support;
|
|
||||||
use crate::support::*;
|
|
||||||
|
|
||||||
use libc;
|
|
||||||
|
|
||||||
#[tokio::test]
|
|
||||||
async fn simple() {
|
|
||||||
let signal = Signal::new(SignalKind::user_defined1()).expect("failed to create signal");
|
|
||||||
|
|
||||||
send_signal(libc::SIGUSR1);
|
|
||||||
|
|
||||||
let _ = with_timeout(signal.into_future()).await;
|
|
||||||
}
|
|
||||||
Reference in New Issue
Block a user