mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-15 00:00:15 +02:00
signal: move into tokio-net (#1463)
This commit is contained in:
@@ -10,7 +10,6 @@ members = [
|
||||
"tokio-macros",
|
||||
"tokio-net",
|
||||
"tokio-process",
|
||||
"tokio-signal",
|
||||
"tokio-sync",
|
||||
"tokio-test",
|
||||
"tokio-timer",
|
||||
|
||||
+1
-1
@@ -48,11 +48,11 @@ jobs:
|
||||
crates:
|
||||
tokio-fs: []
|
||||
tokio-net:
|
||||
- signal
|
||||
- tcp
|
||||
- udp
|
||||
- uds
|
||||
tokio-process: []
|
||||
tokio-signal: []
|
||||
|
||||
# Test crates that are NOT platform specific
|
||||
- template: ci/azure-test-stable.yml
|
||||
|
||||
@@ -9,7 +9,6 @@ tokio-fs = { path = "tokio-fs" }
|
||||
tokio-io = { path = "tokio-io" }
|
||||
tokio-macros = { path = "tokio-macros" }
|
||||
tokio-net = { path = "tokio-net" }
|
||||
tokio-signal = { path = "tokio-signal" }
|
||||
tokio-sync = { path = "tokio-sync" }
|
||||
tokio-timer = { path = "tokio-timer" }
|
||||
tokio-tls = { path = "tokio-tls" }
|
||||
|
||||
+14
-1
@@ -22,6 +22,13 @@ categories = ["asynchronous", "network-programming"]
|
||||
|
||||
[features]
|
||||
async-traits = []
|
||||
signal = [
|
||||
"futures-util-preview",
|
||||
"mio-uds",
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
"winapi",
|
||||
]
|
||||
tcp = [
|
||||
"bytes",
|
||||
"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 }
|
||||
iovec = { version = "0.1", optional = true }
|
||||
|
||||
# UDS
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
# UDS / Signal
|
||||
mio-uds = { version = "0.6.5", 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]
|
||||
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }
|
||||
|
||||
@@ -40,6 +40,9 @@
|
||||
pub mod driver;
|
||||
pub mod util;
|
||||
|
||||
#[cfg(feature = "signal")]
|
||||
pub mod signal;
|
||||
|
||||
#[cfg(feature = "tcp")]
|
||||
pub mod tcp;
|
||||
|
||||
|
||||
@@ -1,9 +1,8 @@
|
||||
#[cfg(unix)]
|
||||
use crate::unix::Signal as Inner;
|
||||
use super::unix::Signal as Inner;
|
||||
#[cfg(windows)]
|
||||
use crate::windows::Event as Inner;
|
||||
|
||||
use tokio_net::driver::Handle;
|
||||
use super::windows::Event as Inner;
|
||||
use crate::driver::Handle;
|
||||
|
||||
use futures_core::stream::Stream;
|
||||
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
|
||||
//!
|
||||
//! This crate implements asynchronous signal handling for Tokio, an
|
||||
@@ -30,6 +20,8 @@
|
||||
//! ```rust,no_run
|
||||
//! #![feature(async_await)]
|
||||
//!
|
||||
//! use tokio_net::signal;
|
||||
//!
|
||||
//! use futures_util::future;
|
||||
//! use futures_util::stream::StreamExt;
|
||||
//!
|
||||
@@ -37,7 +29,7 @@
|
||||
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Create an infinite stream of "Ctrl+C" notifications. Each item received
|
||||
//! // 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
|
||||
//! let prog = ctrl_c.for_each(|_| {
|
||||
@@ -57,15 +49,16 @@
|
||||
//! #![feature(async_await)]
|
||||
//! # #[cfg(unix)] {
|
||||
//!
|
||||
//! use tokio_net::signal::{self, unix::{Signal, SignalKind}};
|
||||
//!
|
||||
//! use futures_util::future;
|
||||
//! use futures_util::stream::StreamExt;
|
||||
//! use tokio_signal::unix::{Signal, SignalKind};
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
//! // Create an infinite stream of "Ctrl+C" notifications. Each item received
|
||||
//! // 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
|
||||
//! let prog = ctrl_c.for_each(|_| {
|
||||
@@ -87,9 +80,6 @@
|
||||
//! # }
|
||||
//! ```
|
||||
|
||||
#[macro_use]
|
||||
extern crate lazy_static;
|
||||
|
||||
mod ctrl_c;
|
||||
mod registry;
|
||||
|
||||
@@ -103,4 +93,4 @@ mod os {
|
||||
pub mod unix;
|
||||
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::pin::Pin;
|
||||
use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Mutex;
|
||||
|
||||
use crate::os::{OsExtraData, OsStorage};
|
||||
use tokio_sync::mpsc::Sender;
|
||||
|
||||
pub(crate) type EventId = usize;
|
||||
|
||||
/// State for a specific event, whether a notification is pending delivery,
|
||||
@@ -5,13 +5,15 @@
|
||||
|
||||
#![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_net::driver::Handle;
|
||||
use tokio_net::util::PollEvented;
|
||||
use tokio_sync::mpsc::{channel, Receiver};
|
||||
|
||||
pub use libc;
|
||||
|
||||
use futures_core::stream::Stream;
|
||||
use libc::c_int;
|
||||
use mio_uds::UnixStream;
|
||||
@@ -22,8 +24,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Once;
|
||||
use std::task::{Context, Poll};
|
||||
|
||||
use crate::registry::{globals, EventId, EventInfo, Globals, Init, Storage};
|
||||
|
||||
pub(crate) type OsStorage = Vec<SignalInfo>;
|
||||
|
||||
// Number of different unix signals
|
||||
@@ -73,7 +73,7 @@ impl SignalKind {
|
||||
/// For example, this can be used for listening for platform-specific
|
||||
/// signals.
|
||||
/// ```rust,no_run
|
||||
/// # use tokio_signal::unix::SignalKind;
|
||||
/// # use tokio_net::signal::unix::SignalKind;
|
||||
/// # let signum = -1;
|
||||
/// // let signum = libc::OS_SPECIFIC_SIGNAL;
|
||||
/// let kind = SignalKind::from_raw(signum);
|
||||
@@ -438,11 +438,6 @@ impl Stream for Signal {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use futures_util::future::FutureExt;
|
||||
use futures_util::StreamExt;
|
||||
use std::time::Duration;
|
||||
use tokio_sync::oneshot;
|
||||
use tokio_timer::Timeout;
|
||||
|
||||
#[test]
|
||||
fn signal_enable_error_on_invalid_input() {
|
||||
@@ -453,25 +448,4 @@ mod tests {
|
||||
fn signal_enable_error_on_forbidden_input() {
|
||||
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)]
|
||||
|
||||
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 futures_core::stream::Stream;
|
||||
@@ -198,11 +198,13 @@ impl Stream for CtrlBreak {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
|
||||
use tokio::timer::Timeout;
|
||||
|
||||
use futures_util::future::FutureExt;
|
||||
use futures_util::stream::StreamExt;
|
||||
use std::future::Future;
|
||||
use std::time::Duration;
|
||||
use tokio_timer::Timeout;
|
||||
|
||||
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"))
|
||||
@@ -210,7 +212,7 @@ mod tests {
|
||||
|
||||
#[tokio::test]
|
||||
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
|
||||
// like sending signals on Unix, so we'll stub out the actual OS
|
||||
@@ -1,10 +1,9 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use libc;
|
||||
|
||||
pub mod support;
|
||||
use crate::support::*;
|
||||
pub mod signal_support;
|
||||
use crate::signal_support::*;
|
||||
|
||||
#[test]
|
||||
fn dropping_loops_does_not_cause_starvation() {
|
||||
+3
-4
@@ -1,11 +1,10 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![feature(async_await)]
|
||||
|
||||
use libc;
|
||||
|
||||
pub mod support;
|
||||
use crate::support::*;
|
||||
pub mod signal_support;
|
||||
use crate::signal_support::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn drop_then_get_a_signal() {
|
||||
+3
-4
@@ -1,11 +1,10 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![feature(async_await)]
|
||||
|
||||
use libc;
|
||||
|
||||
pub mod support;
|
||||
use crate::support::*;
|
||||
pub mod signal_support;
|
||||
use crate::signal_support::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn dropping_signal_does_not_deregister_any_other_instances() {
|
||||
@@ -1,10 +1,10 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
pub mod support;
|
||||
use crate::support::*;
|
||||
pub mod signal_support;
|
||||
use crate::signal_support::*;
|
||||
|
||||
use libc;
|
||||
use std::sync::mpsc::channel;
|
||||
use std::thread;
|
||||
|
||||
@@ -1,11 +1,10 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![feature(async_await)]
|
||||
|
||||
pub mod support;
|
||||
use crate::support::*;
|
||||
|
||||
use libc;
|
||||
pub mod signal_support;
|
||||
use crate::signal_support::*;
|
||||
|
||||
#[tokio::test]
|
||||
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)]
|
||||
#![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;
|
||||
pub use futures_util::stream::StreamExt;
|
||||
use libc::{c_int, getpid, kill};
|
||||
use std::future::Future;
|
||||
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> {
|
||||
Timeout::new(future, Duration::from_secs(1)).map(Result::unwrap)
|
||||
@@ -1,11 +1,10 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![feature(async_await)]
|
||||
|
||||
pub mod support;
|
||||
use crate::support::*;
|
||||
|
||||
use libc;
|
||||
pub mod signal_support;
|
||||
use crate::signal_support::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn twice() {
|
||||
@@ -55,4 +55,4 @@ lazy_static = "1.3"
|
||||
libc = "0.2"
|
||||
log = "0.4"
|
||||
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
|
||||
//! 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
|
||||
//! 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 tokio_net::driver::Handle;
|
||||
use tokio_net::signal::unix::{Signal, SignalKind};
|
||||
use tokio_net::util::PollEvented;
|
||||
use tokio_signal::unix::{Signal, SignalKind};
|
||||
|
||||
use mio::event::Evented;
|
||||
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