mirror of
https://github.com/tokio-rs/tokio.git
synced 2025-09-25 12:00:35 +00:00
net: move into tokio crate (#1683)
A step towards collapsing Tokio sub crates into a single `tokio` crate (#1318). The `net` implementation is now provided by the main `tokio` crate. Functionality can be opted out of by using the various net related feature flags.
This commit is contained in:
parent
03a9378297
commit
227533d456
@ -5,7 +5,6 @@ members = [
|
||||
"tokio-executor",
|
||||
"tokio-io",
|
||||
"tokio-macros",
|
||||
"tokio-net",
|
||||
"tokio-sync",
|
||||
"tokio-test",
|
||||
"tokio-tls",
|
||||
@ -13,5 +12,6 @@ members = [
|
||||
|
||||
# Internal
|
||||
"examples",
|
||||
"build-tests",
|
||||
"tests-build",
|
||||
"tests-integration",
|
||||
]
|
||||
|
@ -28,7 +28,7 @@ jobs:
|
||||
tokio:
|
||||
- fs
|
||||
- io
|
||||
- net
|
||||
- net-driver
|
||||
- process
|
||||
- rt-full
|
||||
- signal
|
||||
@ -37,21 +37,7 @@ jobs:
|
||||
- timer
|
||||
- udp
|
||||
- uds
|
||||
|
||||
# Test crates that are platform specific
|
||||
- template: ci/azure-test-stable.yml
|
||||
parameters:
|
||||
name: test_sub_cross
|
||||
displayName: Test sub crates (cross) -
|
||||
cross: true
|
||||
rust: beta
|
||||
crates:
|
||||
tokio-net:
|
||||
- process
|
||||
- signal
|
||||
- tcp
|
||||
- udp
|
||||
- uds
|
||||
tests-integration: []
|
||||
|
||||
# Test crates that are NOT platform specific
|
||||
- template: ci/azure-test-stable.yml
|
||||
@ -79,21 +65,21 @@ jobs:
|
||||
displayName: Test feature flags
|
||||
rust: beta
|
||||
crates:
|
||||
build-tests:
|
||||
tests-build:
|
||||
- tokio-executor
|
||||
- tokio-net
|
||||
- executor-without-current-thread
|
||||
- macros-invalid-input
|
||||
- net-no-features
|
||||
- net-with-tcp
|
||||
- net-with-udp
|
||||
- net-with-uds
|
||||
- tokio-no-features
|
||||
- tokio-with-net
|
||||
# - macros-invalid-input
|
||||
# - net-no-features
|
||||
# - net-with-tcp
|
||||
# - net-with-udp
|
||||
# - net-with-uds
|
||||
# - tokio-no-features
|
||||
# - tokio-with-net
|
||||
|
||||
# Run loom tests
|
||||
- template: ci/azure-loom.yml
|
||||
parameters:
|
||||
name: loom
|
||||
rust: beta
|
||||
crates:
|
||||
- tokio-executor
|
||||
@ -128,9 +114,9 @@ jobs:
|
||||
- rustfmt
|
||||
- clippy
|
||||
- test_tokio
|
||||
- test_sub_cross
|
||||
- test_linux
|
||||
- test_features
|
||||
- loom
|
||||
# - test_nightly
|
||||
- cross
|
||||
# - minrust
|
||||
|
@ -1,27 +0,0 @@
|
||||
[package]
|
||||
name = "build-tests"
|
||||
version = "0.1.0"
|
||||
authors = ["Tokio Contributors <team@tokio.rs>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
executor-without-current-thread = ["tokio-executor"]
|
||||
macros-invalid-input = ["tokio/rt-full"]
|
||||
net-no-features = ["tokio-net"]
|
||||
net-with-tcp = ["tokio-net/tcp"]
|
||||
net-with-udp = ["tokio-net/udp"]
|
||||
net-with-uds = ["tokio-net/uds"]
|
||||
net-with-process = ["tokio-net/process"]
|
||||
tokio-no-features = ["tokio"]
|
||||
tokio-with-net = ["tokio/net"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tokio-executor = { path = "../tokio-executor", optional = true }
|
||||
tokio-net = { path = "../tokio-net", optional = true }
|
||||
tokio = { path = "../tokio", optional = true, default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0"
|
@ -1,3 +0,0 @@
|
||||
use build_tests::tokio_executor::current_thread;
|
||||
|
||||
fn main() {}
|
@ -1,4 +0,0 @@
|
||||
use build_tests::tokio_net::tcp;
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +0,0 @@
|
||||
use build_tests::tokio_net::udp;
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,4 +0,0 @@
|
||||
use build_tests::tokio_net::uds;
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,3 +0,0 @@
|
||||
use build_tests::tokio::net;
|
||||
|
||||
fn main() {}
|
@ -1,5 +1,5 @@
|
||||
jobs:
|
||||
- job: loom
|
||||
- job: ${{ parameters.name }}
|
||||
displayName: Loom tests
|
||||
pool:
|
||||
vmImage: ubuntu-16.04
|
||||
|
@ -5,7 +5,6 @@ tokio = { path = "tokio" }
|
||||
tokio-executor = { path = "tokio-executor" }
|
||||
tokio-io = { path = "tokio-io" }
|
||||
tokio-macros = { path = "tokio-macros" }
|
||||
tokio-net = { path = "tokio-net" }
|
||||
tokio-sync = { path = "tokio-sync" }
|
||||
tokio-tls = { path = "tokio-tls" }
|
||||
tokio-util = { path = "tokio-util" }
|
||||
|
26
tests-build/Cargo.toml
Normal file
26
tests-build/Cargo.toml
Normal file
@ -0,0 +1,26 @@
|
||||
[package]
|
||||
name = "tests-build"
|
||||
version = "0.1.0"
|
||||
authors = ["Tokio Contributors <team@tokio.rs>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[features]
|
||||
executor-without-current-thread = ["tokio-executor"]
|
||||
# macros-invalid-input = ["tokio/rt-full"]
|
||||
# net-no-features = ["tokio-net"]
|
||||
# net-with-tcp = ["tokio-net/tcp"]
|
||||
# net-with-udp = ["tokio-net/udp"]
|
||||
# net-with-uds = ["tokio-net/uds"]
|
||||
# net-with-process = ["tokio-net/process"]
|
||||
# tokio-no-features = ["tokio"]
|
||||
# tokio-with-net = ["tokio/net-full"]
|
||||
|
||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||
|
||||
[dependencies]
|
||||
tokio-executor = { path = "../tokio-executor", optional = true }
|
||||
# tokio = { path = "../tokio", optional = true, default-features = false }
|
||||
|
||||
[dev-dependencies]
|
||||
trybuild = "1.0"
|
@ -0,0 +1,3 @@
|
||||
use tests_build::tokio_executor::current_thread;
|
||||
|
||||
fn main() {}
|
@ -1,7 +1,7 @@
|
||||
error[E0432]: unresolved import `build_tests::tokio_executor::current_thread`
|
||||
error[E0432]: unresolved import `tests_build::tokio_executor::current_thread`
|
||||
--> $DIR/executor_without_current_thread.rs:1:5
|
||||
|
|
||||
1 | use build_tests::tokio_executor::current_thread;
|
||||
1 | use tests_build::tokio_executor::current_thread;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `current_thread` in `tokio_executor`
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
@ -1,4 +1,4 @@
|
||||
use build_tests::tokio;
|
||||
use tests_build::tokio;
|
||||
|
||||
#[tokio::main]
|
||||
fn main_is_not_async() {}
|
4
tests-build/tests/fail/net_without_tcp_missing_tcp.rs
Normal file
4
tests-build/tests/fail/net_without_tcp_missing_tcp.rs
Normal file
@ -0,0 +1,4 @@
|
||||
use tests_build::tokio_net::tcp;
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
error[E0432]: unresolved import `build_tests::tokio_net::tcp`
|
||||
error[E0432]: unresolved import `tests_build::tokio_net::tcp`
|
||||
--> $DIR/net_without_tcp_missing_tcp.rs:1:5
|
||||
|
|
||||
1 | use build_tests::tokio_net::tcp;
|
||||
1 | use tests_build::tokio_net::tcp;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `tcp` in `tokio_net`
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
4
tests-build/tests/fail/net_without_udp_missing_udp.rs
Normal file
4
tests-build/tests/fail/net_without_udp_missing_udp.rs
Normal file
@ -0,0 +1,4 @@
|
||||
use tests_build::tokio_net::udp;
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
error[E0432]: unresolved import `build_tests::tokio_net::udp`
|
||||
error[E0432]: unresolved import `tests_build::tokio_net::udp`
|
||||
--> $DIR/net_without_udp_missing_udp.rs:1:5
|
||||
|
|
||||
1 | use build_tests::tokio_net::udp;
|
||||
1 | use tests_build::tokio_net::udp;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `udp` in `tokio_net`
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
4
tests-build/tests/fail/net_without_uds_missing_uds.rs
Normal file
4
tests-build/tests/fail/net_without_uds_missing_uds.rs
Normal file
@ -0,0 +1,4 @@
|
||||
use tests_build::tokio_net::uds;
|
||||
|
||||
fn main() {}
|
||||
|
@ -1,7 +1,7 @@
|
||||
error[E0432]: unresolved import `build_tests::tokio_net::uds`
|
||||
error[E0432]: unresolved import `tests_build::tokio_net::uds`
|
||||
--> $DIR/net_without_uds_missing_uds.rs:1:5
|
||||
|
|
||||
1 | use build_tests::tokio_net::uds;
|
||||
1 | use tests_build::tokio_net::uds;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `uds` in `tokio_net`
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
3
tests-build/tests/fail/tokio_without_net_missing_net.rs
Normal file
3
tests-build/tests/fail/tokio_without_net_missing_net.rs
Normal file
@ -0,0 +1,3 @@
|
||||
use tests_build::tokio::net;
|
||||
|
||||
fn main() {}
|
@ -1,7 +1,7 @@
|
||||
error[E0432]: unresolved import `build_tests::tokio::net`
|
||||
error[E0432]: unresolved import `tests_build::tokio::net`
|
||||
--> $DIR/tokio_without_net_missing_net.rs:1:5
|
||||
|
|
||||
1 | use build_tests::tokio::net;
|
||||
1 | use tests_build::tokio::net;
|
||||
| ^^^^^^^^^^^^^^^^^^^^^^^ no `net` in `tokio`
|
||||
|
||||
For more information about this error, try `rustc --explain E0432`.
|
@ -3,39 +3,39 @@
|
||||
#[test]
|
||||
#[cfg(feature = "tokio-net")]
|
||||
fn net_default() {
|
||||
use build_tests::tokio_net::driver::{set_default, Handle, Reactor, Registration};
|
||||
use build_tests::tokio_net::util::PollEvented;
|
||||
use tests_build::tokio_net::driver::{set_default, Handle, Reactor, Registration};
|
||||
use tests_build::tokio_net::util::PollEvented;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "net-with-tcp")]
|
||||
fn net_with_tcp() {
|
||||
use build_tests::tokio_net::tcp;
|
||||
use tests_build::tokio_net::tcp;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "net-with-udp")]
|
||||
fn net_with_udp() {
|
||||
use build_tests::tokio_net::udp;
|
||||
use tests_build::tokio_net::udp;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "net-with-uds")]
|
||||
fn net_with_uds() {
|
||||
use build_tests::tokio_net::uds;
|
||||
use tests_build::tokio_net::uds;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "net-with-process")]
|
||||
fn net_with_process() {
|
||||
use build_tests::tokio_net::process;
|
||||
use tests_build::tokio_net::process;
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[cfg(feature = "tokio-with-net")]
|
||||
fn tokio_with_net() {
|
||||
// net is present
|
||||
use build_tests::tokio::net;
|
||||
use tests_build::tokio::net;
|
||||
}
|
||||
|
||||
#[test]
|
14
tests-integration/Cargo.toml
Normal file
14
tests-integration/Cargo.toml
Normal file
@ -0,0 +1,14 @@
|
||||
[package]
|
||||
name = "tests-integration"
|
||||
version = "0.1.0"
|
||||
authors = ["Tokio Contributors <team@tokio.rs>"]
|
||||
edition = "2018"
|
||||
publish = false
|
||||
|
||||
[dependencies]
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { path = "../tokio" }
|
||||
tokio-test = { path = "../tokio-test" }
|
||||
|
||||
futures-preview = { version = "=0.3.0-alpha.19", features = ["async-await"] }
|
1
tests-integration/README.md
Normal file
1
tests-integration/README.md
Normal file
@ -0,0 +1 @@
|
||||
Tests that require additional components than just the `tokio` crate.
|
@ -1,19 +1,15 @@
|
||||
#![cfg(feature = "process")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use tokio::io::{AsyncBufReadExt, AsyncWriteExt, BufReader};
|
||||
use tokio_net::process::{Child, Command};
|
||||
use tokio::process::{Child, Command};
|
||||
use tokio_test::assert_ok;
|
||||
|
||||
use futures_util::future;
|
||||
use futures_util::future::FutureExt;
|
||||
use futures_util::stream::StreamExt;
|
||||
use futures::future::{self, FutureExt};
|
||||
use futures::stream::StreamExt;
|
||||
use std::env;
|
||||
use std::io;
|
||||
use std::process::{ExitStatus, Stdio};
|
||||
|
||||
mod support;
|
||||
use support::*;
|
||||
|
||||
fn cat() -> Command {
|
||||
let mut me = env::current_exe().unwrap();
|
||||
me.pop();
|
||||
@ -95,7 +91,7 @@ async fn feed_cat(mut cat: Child, n: usize) -> io::Result<ExitStatus> {
|
||||
#[tokio::test]
|
||||
async fn feed_a_lot() {
|
||||
let child = cat().spawn().unwrap();
|
||||
let status = with_timeout(feed_cat(child, 10000)).await.unwrap();
|
||||
let status = feed_cat(child, 10000).await.unwrap();
|
||||
assert_eq!(status.code(), Some(0));
|
||||
}
|
||||
|
||||
@ -113,7 +109,7 @@ async fn wait_with_output_captures() {
|
||||
out.await
|
||||
};
|
||||
|
||||
let output = with_timeout(future).await.unwrap();
|
||||
let output = future.await.unwrap();
|
||||
|
||||
assert!(output.status.success());
|
||||
assert_eq!(output.stdout, write_bytes);
|
||||
@ -127,7 +123,5 @@ async fn status_closes_any_pipes() {
|
||||
// we would end up blocking forever (and time out).
|
||||
let child = cat().status();
|
||||
|
||||
with_timeout(child)
|
||||
.await
|
||||
.expect("time out exceeded! did we get stuck waiting on the child?");
|
||||
assert_ok!(child.await);
|
||||
}
|
@ -2,14 +2,18 @@
|
||||
|
||||
use crate::loom::sync::{Arc, Condvar, Mutex};
|
||||
use crate::loom::thread;
|
||||
#[cfg(feature = "blocking")]
|
||||
use tokio_sync::oneshot;
|
||||
|
||||
use std::cell::Cell;
|
||||
use std::collections::VecDeque;
|
||||
use std::fmt;
|
||||
#[cfg(feature = "blocking")]
|
||||
use std::future::Future;
|
||||
use std::ops::Deref;
|
||||
#[cfg(feature = "blocking")]
|
||||
use std::pin::Pin;
|
||||
#[cfg(feature = "blocking")]
|
||||
use std::task::{Context, Poll};
|
||||
use std::time::Duration;
|
||||
|
||||
@ -88,6 +92,7 @@ const MAX_THREADS: u32 = 1_000;
|
||||
const KEEP_ALIVE: Duration = Duration::from_secs(10);
|
||||
|
||||
/// Result of a blocking operation running on the blocking thread pool.
|
||||
#[cfg(feature = "blocking")]
|
||||
#[derive(Debug)]
|
||||
pub struct Blocking<T> {
|
||||
rx: oneshot::Receiver<T>,
|
||||
@ -259,6 +264,7 @@ impl Drop for PoolWaiter {
|
||||
/// }).await;
|
||||
/// # }
|
||||
/// ```
|
||||
#[cfg(feature = "blocking")]
|
||||
pub fn run<F, R>(f: F) -> Blocking<R>
|
||||
where
|
||||
F: FnOnce() -> R + Send + 'static,
|
||||
@ -283,6 +289,7 @@ where
|
||||
Blocking { rx }
|
||||
}
|
||||
|
||||
#[cfg(feature = "blocking")]
|
||||
impl<T> Future for Blocking<T> {
|
||||
type Output = T;
|
||||
|
||||
|
@ -1,98 +0,0 @@
|
||||
# 0.2.0-alpha.6 (September 30, 2019)
|
||||
|
||||
- Move to `futures-*-preview 0.3.0-alpha.19`
|
||||
- Move to `pin-project 0.4`
|
||||
|
||||
# 0.2.0-alpha.5 (September 19, 2019)
|
||||
|
||||
### Added
|
||||
- platform specific `Command` methods (#1516).
|
||||
- Implement `From<std::process::Command>` for `Command` (#1513).
|
||||
|
||||
### Fixed
|
||||
- doc generation (#1575).
|
||||
|
||||
# 0.2.0-alpha.4 (August 29, 2019)
|
||||
|
||||
- Track tokio release.
|
||||
|
||||
# 0.2.0-alpha.3 (August 28, 2019)
|
||||
|
||||
### Changed
|
||||
- `signal::ctrl_c()` instead of `CtrlC::new()` (#1472).
|
||||
- `TcpStream`'s `AsyncWrite::shutdown` impl calls TCP shutdown (#1488).
|
||||
- use `tracing` instead of `log` (#1455).
|
||||
- perform DNS lookup on `connect` and `bind` (#1499).
|
||||
|
||||
### Added
|
||||
- import `tokio-process` (#1475).
|
||||
|
||||
# 0.2.0-alpha.2 (August 17, 2019)
|
||||
|
||||
### Changed
|
||||
- Renamed `tokio-net` from `tokio-reactor` (#1450).
|
||||
- Switch `with_default(..., || )` to `set_default(...) -> Guard` (#1449).
|
||||
- Update `futures` dependency to 0.3.0-alpha.18.
|
||||
|
||||
### Added
|
||||
- Import `tokio-tcp` (#1456).
|
||||
- Import `tokio-udp` (#1459).
|
||||
- Import `tokio-uds` (#1462).
|
||||
- Import `tokio-signal` (#1463).
|
||||
|
||||
# 0.2.0-alpha.1 (August 8, 2019)
|
||||
|
||||
### Changed
|
||||
- Switch to `async`, `await`, and `std::future`.
|
||||
|
||||
# 0.1.9 (March 1, 2019)
|
||||
|
||||
### Added
|
||||
- impl `AsRawFd` for `Reactor` on unix platforms (#890).
|
||||
|
||||
### Changed
|
||||
- perf: reduce unnecessary task clones (#899).
|
||||
- perf: release lock before issuing syscall (#894).
|
||||
|
||||
# 0.1.8 (January 6, 2019)
|
||||
|
||||
* Update to `parking_lot` 0.7 (#778).
|
||||
* Deprecate `Handle::current()` (#805).
|
||||
|
||||
# 0.1.7 (November 21, 2018)
|
||||
|
||||
* Reduce log level to trace (#734).
|
||||
* Bump internal dependency versions (#746).
|
||||
|
||||
# 0.1.6 (September 27, 2018)
|
||||
|
||||
* Fix panic when reactor is stored in a thread-local (#628).
|
||||
|
||||
# 0.1.5 (August 27, 2018)
|
||||
|
||||
* Experimental async / await support.
|
||||
|
||||
# 0.1.4 (August 23, 2018)
|
||||
|
||||
* Use a scalable RW lock (#517)
|
||||
* Implement std::error::Error for error types (#511)
|
||||
* Documentation improvements
|
||||
|
||||
# 0.1.3 (August 6, 2018)
|
||||
|
||||
* Misc small fixes (#508)
|
||||
|
||||
# 0.1.2 (June 13, 2018)
|
||||
|
||||
* Fix deadlock that can happen when shutting down (#409)
|
||||
* Handle::default() lazily binds to reactor (#350)
|
||||
|
||||
# 0.1.1 (March 22, 2018)
|
||||
|
||||
* Fix threading bugs (#227)
|
||||
* Fix notification bugs (#243)
|
||||
* Optionally support futures 0.2 (#172)
|
||||
|
||||
# 0.1.0 (March 09, 2018)
|
||||
|
||||
* Initial release
|
@ -1,109 +0,0 @@
|
||||
[package]
|
||||
name = "tokio-net"
|
||||
# When releasing to crates.io:
|
||||
# - Remove path dependencies
|
||||
# - Update html_root_url.
|
||||
# - Update doc url
|
||||
# - Cargo.toml
|
||||
# - Update CHANGELOG.md.
|
||||
# - Create "v0.2.x" git tag.
|
||||
version = "0.2.0-alpha.6"
|
||||
edition = "2018"
|
||||
authors = ["Tokio Contributors <team@tokio.rs>"]
|
||||
license = "MIT"
|
||||
readme = "README.md"
|
||||
repository = "https://github.com/tokio-rs/tokio"
|
||||
homepage = "https://tokio.rs"
|
||||
documentation = "https://docs.rs/tokio-net/0.2.0-alpha.6/tokio_net"
|
||||
description = """
|
||||
Event loop that drives Tokio I/O resources.
|
||||
"""
|
||||
categories = ["asynchronous", "network-programming"]
|
||||
|
||||
[features]
|
||||
async-traits = []
|
||||
process = [
|
||||
"tokio-io/util",
|
||||
"crossbeam-queue",
|
||||
"libc",
|
||||
"mio-named-pipes",
|
||||
"signal",
|
||||
"winapi/handleapi",
|
||||
"winapi/winerror",
|
||||
"winapi/minwindef",
|
||||
"winapi/processthreadsapi",
|
||||
"winapi/synchapi",
|
||||
"winapi/threadpoollegacyapiset",
|
||||
"winapi/winbase",
|
||||
"winapi/winnt",
|
||||
]
|
||||
signal = [
|
||||
"mio-uds",
|
||||
"libc",
|
||||
"signal-hook-registry",
|
||||
"winapi/consoleapi",
|
||||
"winapi/minwindef",
|
||||
"winapi/wincon"
|
||||
]
|
||||
tcp = [
|
||||
"bytes",
|
||||
"iovec",
|
||||
]
|
||||
udp = [
|
||||
"bytes",
|
||||
"futures-sink-preview",
|
||||
]
|
||||
uds = [
|
||||
"bytes",
|
||||
"mio-uds",
|
||||
"iovec",
|
||||
"libc",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
tokio-executor = { version = "=0.2.0-alpha.6", features = ["blocking"], path = "../tokio-executor" }
|
||||
tokio-io = { version = "=0.2.0-alpha.6", path = "../tokio-io" }
|
||||
tokio-sync = { version = "=0.2.0-alpha.6", path = "../tokio-sync" }
|
||||
|
||||
# driver implementation
|
||||
crossbeam-utils = "0.6.0"
|
||||
futures-core-preview = "=0.3.0-alpha.19"
|
||||
futures-util-preview = "=0.3.0-alpha.19"
|
||||
lazy_static = "1.0.2"
|
||||
mio = "0.6.14"
|
||||
num_cpus = "1.8.0"
|
||||
parking_lot = "0.9"
|
||||
slab = "0.4.0"
|
||||
|
||||
# TCP / UDP
|
||||
bytes = { version = "0.4", optional = true }
|
||||
futures-sink-preview = { version = "=0.3.0-alpha.19", optional = true }
|
||||
iovec = { version = "0.1", optional = true }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
# UDS / Signal
|
||||
crossbeam-queue = { version = "0.1.2", optional = true }
|
||||
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]
|
||||
mio-named-pipes = { version = "0.1", optional = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies.winapi]
|
||||
version = "0.3"
|
||||
default-features = false
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "=0.2.0-alpha.6", path = "../tokio" }
|
||||
tokio-test = { version = "=0.2.0-alpha.6", path = "../tokio-test" }
|
||||
num_cpus = "1.8.0"
|
||||
tokio-io-pool = "0.1.4"
|
||||
|
||||
# UDS tests
|
||||
tempfile = "3"
|
||||
futures-preview = { version = "=0.3.0-alpha.19", features = ["async-await"] }
|
||||
|
||||
[package.metadata.docs.rs]
|
||||
all-features = true
|
@ -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-reactor
|
||||
|
||||
Event loop that drives Tokio I/O resources.
|
||||
|
||||
## 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,63 +0,0 @@
|
||||
#![doc(html_root_url = "https://docs.rs/tokio-net/0.2.0-alpha.6")]
|
||||
#![warn(
|
||||
missing_debug_implementations,
|
||||
missing_docs,
|
||||
rust_2018_idioms,
|
||||
unreachable_pub
|
||||
)]
|
||||
#![deny(intra_doc_link_resolution_failure)]
|
||||
#![doc(test(
|
||||
no_crate_inject,
|
||||
attr(deny(warnings, rust_2018_idioms), allow(dead_code, unused_variables))
|
||||
))]
|
||||
|
||||
//! Event loop that drives Tokio I/O resources.
|
||||
//!
|
||||
//! The reactor is the engine that drives asynchronous I/O resources (like TCP and
|
||||
//! UDP sockets). It is backed by [`mio`] and acts as a bridge between [`mio`] and
|
||||
//! [`futures`].
|
||||
//!
|
||||
//! The crate provides:
|
||||
//!
|
||||
//! * [`Reactor`] is the main type of this crate. It performs the event loop logic.
|
||||
//!
|
||||
//! * [`Handle`] provides a reference to a reactor instance.
|
||||
//!
|
||||
//! * [`Registration`] and [`PollEvented`] allow third parties to implement I/O
|
||||
//! resources that are driven by the reactor.
|
||||
//!
|
||||
//! Application authors will not use this crate directly. Instead, they will use the
|
||||
//! `tokio` crate. Library authors should only depend on `tokio-net` if they
|
||||
//! are building a custom I/O resource.
|
||||
//!
|
||||
//! For more details, see [reactor module] documentation in the Tokio crate.
|
||||
//!
|
||||
//! [`mio`]: http://github.com/carllerche/mio
|
||||
//! [`futures`]: http://github.com/rust-lang-nursery/futures-rs
|
||||
//! [`Reactor`]: struct.Reactor.html
|
||||
//! [`Handle`]: struct.Handle.html
|
||||
//! [`Registration`]: struct.Registration.html
|
||||
//! [`PollEvented`]: struct.PollEvented.html
|
||||
//! [reactor module]: https://docs.rs/tokio/0.1/tokio/reactor/index.html
|
||||
|
||||
mod addr;
|
||||
pub use addr::ToSocketAddrs;
|
||||
|
||||
pub mod driver;
|
||||
pub mod util;
|
||||
|
||||
#[cfg(feature = "process")]
|
||||
pub mod process;
|
||||
|
||||
#[cfg(feature = "signal")]
|
||||
pub mod signal;
|
||||
|
||||
#[cfg(feature = "tcp")]
|
||||
pub mod tcp;
|
||||
|
||||
#[cfg(feature = "udp")]
|
||||
pub mod udp;
|
||||
|
||||
#[cfg(feature = "uds")]
|
||||
#[cfg(unix)]
|
||||
pub mod uds;
|
@ -1,36 +0,0 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod support;
|
||||
use support::*;
|
||||
|
||||
#[tokio::test]
|
||||
async fn simple() {
|
||||
let signal = signal(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::ctrl_c;
|
||||
|
||||
let ctrl_c = ctrl_c().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,34 +0,0 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![allow(dead_code)]
|
||||
|
||||
pub use tokio::runtime::current_thread::{self, Runtime as CurrentThreadRuntime};
|
||||
use tokio::timer::Timeout;
|
||||
|
||||
#[cfg(all(unix, feature = "signal"))]
|
||||
pub use tokio_net::signal::unix::{signal, SignalKind};
|
||||
|
||||
pub use futures_util::future;
|
||||
use futures_util::future::FutureExt;
|
||||
pub use futures_util::stream::StreamExt;
|
||||
#[cfg(unix)]
|
||||
use libc::{c_int, getpid, kill};
|
||||
use std::future::Future;
|
||||
use std::time::Duration;
|
||||
|
||||
pub fn with_timeout<F: Future>(future: F) -> impl Future<Output = F::Output> {
|
||||
Timeout::new(future, Duration::from_secs(3)).map(Result::unwrap)
|
||||
}
|
||||
|
||||
pub fn run_with_timeout<F>(rt: &mut CurrentThreadRuntime, future: F) -> F::Output
|
||||
where
|
||||
F: Future,
|
||||
{
|
||||
rt.block_on(with_timeout(future))
|
||||
}
|
||||
|
||||
#[cfg(unix)]
|
||||
pub fn send_signal(signal: c_int) {
|
||||
unsafe {
|
||||
assert_eq!(kill(getpid(), signal), 0);
|
||||
}
|
||||
}
|
@ -30,7 +30,6 @@ tokio-io = { version = "=0.2.0-alpha.6", path = "../tokio-io" }
|
||||
|
||||
[dev-dependencies]
|
||||
tokio = { version = "=0.2.0-alpha.6", path = "../tokio" }
|
||||
tokio-net = { version = "=0.2.0-alpha.6", path = "../tokio-net", features = ["tcp", "async-traits"] }
|
||||
|
||||
cfg-if = "0.1"
|
||||
env_logger = { version = "0.6", default-features = false }
|
||||
|
@ -27,7 +27,7 @@ keywords = ["io", "async", "non-blocking", "futures"]
|
||||
default = [
|
||||
"fs",
|
||||
"io",
|
||||
"net",
|
||||
"net-full",
|
||||
"process",
|
||||
"rt-full",
|
||||
"signal",
|
||||
@ -35,31 +35,47 @@ default = [
|
||||
"timer",
|
||||
]
|
||||
|
||||
fs = []
|
||||
io = ["tokio-io"]
|
||||
fs = ["tokio-executor/blocking"]
|
||||
io = ["tokio-io", "bytes", "iovec"]
|
||||
macros = ["tokio-macros"]
|
||||
net = ["tcp", "udp", "uds"]
|
||||
net-full = ["tcp", "udp", "uds"]
|
||||
net-driver = ["mio", "tokio-executor/blocking"]
|
||||
rt-current-thread = [
|
||||
"timer",
|
||||
"tokio-net",
|
||||
"tokio-executor/current-thread",
|
||||
]
|
||||
rt-full = [
|
||||
"macros",
|
||||
"num_cpus",
|
||||
"net",
|
||||
"net-full",
|
||||
"sync",
|
||||
"timer",
|
||||
"tokio-executor/current-thread",
|
||||
"tokio-executor/thread-pool",
|
||||
]
|
||||
signal = ["tokio-net/signal"]
|
||||
signal = [
|
||||
"lazy_static",
|
||||
"libc",
|
||||
"mio-uds",
|
||||
"net-driver",
|
||||
"signal-hook-registry"
|
||||
]
|
||||
sync = ["tokio-sync"]
|
||||
tcp = ["io", "tokio-net/tcp"]
|
||||
tcp = ["io", "net-driver"]
|
||||
timer = ["crossbeam-utils", "slab"]
|
||||
udp = ["io", "tokio-net/udp"]
|
||||
uds = ["io", "tokio-net/uds"]
|
||||
process = ["io", "tokio-net/process"]
|
||||
udp = ["io", "net-driver"]
|
||||
uds = ["io", "net-driver", "mio-uds", "libc"]
|
||||
process = [
|
||||
"crossbeam-queue",
|
||||
"io",
|
||||
"libc",
|
||||
"mio-named-pipes",
|
||||
"signal",
|
||||
"winapi/consoleapi",
|
||||
"winapi/minwindef",
|
||||
"winapi/threadpoollegacyapiset",
|
||||
"winapi/winerror",
|
||||
]
|
||||
|
||||
[dependencies]
|
||||
futures-core-preview = "=0.3.0-alpha.19"
|
||||
@ -67,23 +83,38 @@ futures-sink-preview = "=0.3.0-alpha.19"
|
||||
futures-util-preview = { version = "=0.3.0-alpha.19", features = ["sink"] }
|
||||
|
||||
# Everything else is optional...
|
||||
bytes = { version = "0.4", optional = true }
|
||||
crossbeam-utils = { version = "0.6.0", optional = true }
|
||||
iovec = { version = "0.1", optional = true }
|
||||
lazy_static = { version = "1.0.2", optional = true }
|
||||
mio = { version = "0.6.14", optional = true }
|
||||
num_cpus = { version = "1.8.0", optional = true }
|
||||
# Backs `DelayQueue`
|
||||
slab = { version = "0.4.1", optional = true }
|
||||
tokio-io = { version = "=0.2.0-alpha.6", optional = true, features = ["util"], path = "../tokio-io" }
|
||||
tokio-executor = { version = "=0.2.0-alpha.6", optional = true, path = "../tokio-executor" }
|
||||
tokio-macros = { version = "=0.2.0-alpha.6", optional = true, path = "../tokio-macros" }
|
||||
tokio-net = { version = "=0.2.0-alpha.6", optional = true, features = ["async-traits"], path = "../tokio-net" }
|
||||
tokio-sync = { version = "=0.2.0-alpha.6", optional = true, path = "../tokio-sync", features = ["async-traits"] }
|
||||
|
||||
[target.'cfg(unix)'.dependencies]
|
||||
crossbeam-queue = { version = "0.1.2", optional = true }
|
||||
mio-uds = { version = "0.6.5", optional = true }
|
||||
libc = { version = "0.2.42", optional = true }
|
||||
signal-hook-registry = { version = "1.1.1", optional = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies]
|
||||
mio-named-pipes = { version = "0.1.6", optional = true }
|
||||
|
||||
[target.'cfg(windows)'.dependencies.winapi]
|
||||
version = "0.3.8"
|
||||
default-features = false
|
||||
optional = true
|
||||
|
||||
[dev-dependencies]
|
||||
tokio-test = { version = "=0.2.0-alpha.6", path = "../tokio-test" }
|
||||
tokio-util = { version = "=0.2.0-alpha.6", path = "../tokio-util" }
|
||||
|
||||
futures-preview = "=0.3.0-alpha.19"
|
||||
futures-util-preview = "=0.3.0-alpha.19"
|
||||
pin-utils = "=0.1.0-alpha.4"
|
||||
futures-preview = { version = "=0.3.0-alpha.19", features = ["async-await"] }
|
||||
env_logger = { version = "0.6", default-features = false }
|
||||
flate2 = { version = "1", features = ["tokio"] }
|
||||
http = "0.1"
|
||||
|
@ -26,7 +26,7 @@
|
||||
//!
|
||||
//! Guide level documentation is found on the [website].
|
||||
//!
|
||||
//! [driver]: tokio_net::driver
|
||||
//! [driver]: tokio::net::driver
|
||||
//! [website]: https://tokio.rs/docs/
|
||||
//!
|
||||
//! # Examples
|
||||
@ -82,23 +82,34 @@ macro_rules! if_runtime {
|
||||
|
||||
#[cfg(feature = "timer")]
|
||||
pub mod clock;
|
||||
|
||||
#[cfg(feature = "codec")]
|
||||
pub mod codec;
|
||||
|
||||
#[cfg(feature = "fs")]
|
||||
pub mod fs;
|
||||
|
||||
pub mod future;
|
||||
|
||||
#[cfg(feature = "io")]
|
||||
pub mod io;
|
||||
#[cfg(any(feature = "tcp", feature = "udp", feature = "uds"))]
|
||||
|
||||
#[cfg(feature = "net-driver")]
|
||||
pub mod net;
|
||||
|
||||
pub mod prelude;
|
||||
|
||||
#[cfg(feature = "process")]
|
||||
pub mod process;
|
||||
|
||||
#[cfg(feature = "signal")]
|
||||
pub mod signal;
|
||||
|
||||
pub mod stream;
|
||||
|
||||
#[cfg(feature = "sync")]
|
||||
pub mod sync;
|
||||
|
||||
#[cfg(feature = "timer")]
|
||||
pub mod timer;
|
||||
|
||||
@ -113,6 +124,7 @@ if_runtime! {
|
||||
#[cfg(feature = "macros")]
|
||||
#[doc(inline)]
|
||||
pub use tokio_macros::main;
|
||||
|
||||
#[cfg(feature = "macros")]
|
||||
#[doc(inline)]
|
||||
pub use tokio_macros::test;
|
||||
|
@ -1,67 +0,0 @@
|
||||
//! TCP/UDP/Unix bindings for `tokio`.
|
||||
//!
|
||||
//! This module contains the TCP/UDP/Unix networking types, similar to the standard
|
||||
//! library, which can be used to implement networking protocols.
|
||||
//!
|
||||
//! # Organization
|
||||
//!
|
||||
//! * [`TcpListener`] and [`TcpStream`] provide functionality for communication over TCP
|
||||
//! * [`UdpSocket`] provides functionality for communication over UDP
|
||||
//! * [`UnixListener`] and [`UnixStream`] provide functionality for communication over a
|
||||
//! Unix Domain Stream Socket **(available on Unix only)**
|
||||
//! * [`UnixDatagram`] and [`UnixDatagramFramed`] provide functionality for communication
|
||||
//! over Unix Domain Datagram Socket **(available on Unix only)**
|
||||
|
||||
//!
|
||||
//! [`TcpListener`]: struct.TcpListener.html
|
||||
//! [`TcpStream`]: struct.TcpStream.html
|
||||
//! [`UdpSocket`]: struct.UdpSocket.html
|
||||
//! [`UnixListener`]: struct.UnixListener.html
|
||||
//! [`UnixStream`]: struct.UnixStream.html
|
||||
//! [`UnixDatagram`]: struct.UnixDatagram.html
|
||||
//! [`UnixDatagramFramed`]: struct.UnixDatagramFramed.html
|
||||
|
||||
#[cfg(feature = "tcp")]
|
||||
pub mod tcp {
|
||||
//! TCP bindings for `tokio`.
|
||||
//!
|
||||
//! Connecting to an address, via TCP, can be done using [`TcpStream`]'s
|
||||
//! [`connect`] method, which returns [`ConnectFuture`]. `ConnectFuture`
|
||||
//! implements a future which returns a `TcpStream`.
|
||||
//!
|
||||
//! To listen on an address [`TcpListener`] can be used. `TcpListener`'s
|
||||
//! [`incoming`][incoming_method] method can be used to accept new connections.
|
||||
//! It return the [`Incoming`] struct, which implements a stream which returns
|
||||
//! `TcpStream`s.
|
||||
//!
|
||||
//! [`TcpStream`]: struct.TcpStream.html
|
||||
//! [`connect`]: struct.TcpStream.html#method.connect
|
||||
//! [`ConnectFuture`]: struct.ConnectFuture.html
|
||||
//! [`TcpListener`]: struct.TcpListener.html
|
||||
//! [incoming_method]: struct.TcpListener.html#method.incoming
|
||||
//! [`Incoming`]: struct.Incoming.html
|
||||
pub use tokio_net::tcp::{split, Incoming, TcpListener, TcpStream};
|
||||
}
|
||||
#[cfg(feature = "tcp")]
|
||||
pub use self::tcp::{TcpListener, TcpStream};
|
||||
|
||||
#[cfg(feature = "udp")]
|
||||
pub mod udp {
|
||||
//! UDP bindings for `tokio`.
|
||||
//!
|
||||
//! The main struct for UDP is the [`UdpSocket`], which represents a UDP socket.
|
||||
//!
|
||||
//! [`UdpSocket`]: struct.UdpSocket.html
|
||||
pub use tokio_net::udp::{split, UdpSocket};
|
||||
}
|
||||
#[cfg(feature = "udp")]
|
||||
pub use self::udp::UdpSocket;
|
||||
|
||||
#[cfg(all(unix, feature = "uds"))]
|
||||
pub mod unix {
|
||||
//! Unix domain socket bindings for `tokio` (only available on unix systems).
|
||||
|
||||
pub use tokio_net::uds::{split, UCred, UnixDatagram, UnixListener, UnixStream};
|
||||
}
|
||||
#[cfg(all(unix, feature = "uds"))]
|
||||
pub use self::unix::{UnixDatagram, UnixListener, UnixStream};
|
@ -128,7 +128,6 @@
|
||||
pub(crate) mod platform;
|
||||
mod reactor;
|
||||
mod registration;
|
||||
mod sharded_rwlock;
|
||||
|
||||
pub use self::reactor::{set_default, DefaultGuard, Handle, Reactor};
|
||||
pub use self::registration::Registration;
|
@ -1,5 +1,4 @@
|
||||
use super::platform;
|
||||
use super::sharded_rwlock::RwLock;
|
||||
|
||||
use tokio_executor::park::{Park, Unpark};
|
||||
use tokio_sync::AtomicWaker;
|
||||
@ -13,7 +12,7 @@ use std::marker::PhantomData;
|
||||
use std::os::unix::io::{AsRawFd, RawFd};
|
||||
use std::sync::atomic::AtomicUsize;
|
||||
use std::sync::atomic::Ordering::{Relaxed, SeqCst};
|
||||
use std::sync::{Arc, Weak};
|
||||
use std::sync::{Arc, RwLock, Weak};
|
||||
use std::task::Waker;
|
||||
use std::time::Duration;
|
||||
use std::{fmt, usize};
|
||||
@ -207,7 +206,7 @@ impl Reactor {
|
||||
/// Idle is defined as all tasks that have been spawned have completed,
|
||||
/// either successfully or with an error.
|
||||
pub fn is_idle(&self) -> bool {
|
||||
self.inner.io_dispatch.read().is_empty()
|
||||
self.inner.io_dispatch.read().unwrap().is_empty()
|
||||
}
|
||||
|
||||
fn poll(&mut self, max_wait: Option<Duration>) -> io::Result<()> {
|
||||
@ -246,7 +245,7 @@ impl Reactor {
|
||||
// Create a scope to ensure that notifying the tasks stays out of the
|
||||
// lock's critical section.
|
||||
{
|
||||
let io_dispatch = self.inner.io_dispatch.read();
|
||||
let io_dispatch = self.inner.io_dispatch.read().unwrap();
|
||||
|
||||
let io = match io_dispatch.get(token) {
|
||||
Some(io) => io,
|
||||
@ -369,7 +368,7 @@ impl Inner {
|
||||
|
||||
let key = {
|
||||
// Block to contain the write lock
|
||||
let mut io_dispatch = self.io_dispatch.write();
|
||||
let mut io_dispatch = self.io_dispatch.write().unwrap();
|
||||
|
||||
if io_dispatch.len() == MAX_SOURCES {
|
||||
return Err(io::Error::new(
|
||||
@ -405,12 +404,12 @@ impl Inner {
|
||||
}
|
||||
|
||||
pub(super) fn drop_source(&self, token: usize) {
|
||||
self.io_dispatch.write().remove(token);
|
||||
self.io_dispatch.write().unwrap().remove(token);
|
||||
}
|
||||
|
||||
/// Registers interest in the I/O resource associated with `token`.
|
||||
pub(super) fn register(&self, token: usize, dir: Direction, w: Waker) {
|
||||
let io_dispatch = self.io_dispatch.read();
|
||||
let io_dispatch = self.io_dispatch.read().unwrap();
|
||||
let sched = io_dispatch.get(token).unwrap();
|
||||
|
||||
let (waker, ready) = match dir {
|
||||
@ -431,7 +430,7 @@ impl Drop for Inner {
|
||||
// When a reactor is dropped it needs to wake up all blocked tasks as
|
||||
// they'll never receive a notification, and all connected I/O objects
|
||||
// will start returning errors pretty quickly.
|
||||
let io = self.io_dispatch.read();
|
||||
let io = self.io_dispatch.read().unwrap();
|
||||
for (_, io) in io.iter() {
|
||||
io.writer.wake();
|
||||
io.reader.wake();
|
@ -219,7 +219,7 @@ impl Registration {
|
||||
let mask = direction.mask();
|
||||
let mask_no_hup = (mask - platform::hup()).as_usize();
|
||||
|
||||
let io_dispatch = inner.io_dispatch.read();
|
||||
let io_dispatch = inner.io_dispatch.read().unwrap();
|
||||
let sched = &io_dispatch[self.token];
|
||||
|
||||
// This consumes the current readiness state **except** for HUP. HUP is
|
47
tokio/src/net/mod.rs
Normal file
47
tokio/src/net/mod.rs
Normal file
@ -0,0 +1,47 @@
|
||||
//! TCP/UDP/Unix bindings for `tokio`.
|
||||
//!
|
||||
//! This module contains the TCP/UDP/Unix networking types, similar to the standard
|
||||
//! library, which can be used to implement networking protocols.
|
||||
//!
|
||||
//! # Organization
|
||||
//!
|
||||
//! * [`TcpListener`] and [`TcpStream`] provide functionality for communication over TCP
|
||||
//! * [`UdpSocket`] provides functionality for communication over UDP
|
||||
//! * [`UnixListener`] and [`UnixStream`] provide functionality for communication over a
|
||||
//! Unix Domain Stream Socket **(available on Unix only)**
|
||||
//! * [`UnixDatagram`] and [`UnixDatagramFramed`] provide functionality for communication
|
||||
//! over Unix Domain Datagram Socket **(available on Unix only)**
|
||||
|
||||
//!
|
||||
//! [`TcpListener`]: struct.TcpListener.html
|
||||
//! [`TcpStream`]: struct.TcpStream.html
|
||||
//! [`UdpSocket`]: struct.UdpSocket.html
|
||||
//! [`UnixListener`]: struct.UnixListener.html
|
||||
//! [`UnixStream`]: struct.UnixStream.html
|
||||
//! [`UnixDatagram`]: struct.UnixDatagram.html
|
||||
//! [`UnixDatagramFramed`]: struct.UnixDatagramFramed.html
|
||||
|
||||
mod addr;
|
||||
pub use addr::ToSocketAddrs;
|
||||
|
||||
pub mod driver;
|
||||
|
||||
pub mod util;
|
||||
|
||||
#[cfg(feature = "tcp")]
|
||||
pub mod tcp;
|
||||
|
||||
#[cfg(feature = "tcp")]
|
||||
pub use self::tcp::{TcpListener, TcpStream};
|
||||
|
||||
#[cfg(feature = "udp")]
|
||||
pub mod udp;
|
||||
|
||||
#[cfg(feature = "udp")]
|
||||
pub use self::udp::UdpSocket;
|
||||
|
||||
#[cfg(all(unix, feature = "uds"))]
|
||||
pub mod unix;
|
||||
|
||||
#[cfg(all(unix, feature = "uds"))]
|
||||
pub use self::unix::{UnixDatagram, UnixListener, UnixStream};
|
@ -1,5 +1,5 @@
|
||||
use super::TcpListener;
|
||||
use super::TcpStream;
|
||||
use crate::net::tcp::TcpListener;
|
||||
use crate::net::tcp::TcpStream;
|
||||
|
||||
use futures_core::ready;
|
||||
use futures_core::stream::Stream;
|
@ -1,12 +1,9 @@
|
||||
#[cfg(feature = "async-traits")]
|
||||
use super::incoming::Incoming;
|
||||
use super::TcpStream;
|
||||
use crate::util::PollEvented;
|
||||
use crate::ToSocketAddrs;
|
||||
use crate::net::tcp::{Incoming, TcpStream};
|
||||
use crate::net::util::PollEvented;
|
||||
use crate::net::ToSocketAddrs;
|
||||
|
||||
use futures_core::ready;
|
||||
use futures_util::future::poll_fn;
|
||||
use mio;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::io;
|
||||
@ -245,7 +242,6 @@ impl TcpListener {
|
||||
/// necessarily fatal ‒ for example having too many open file descriptors or the other side
|
||||
/// closing the connection while it waits in an accept queue. These would terminate the stream
|
||||
/// if not handled in any way.
|
||||
#[cfg(feature = "async-traits")]
|
||||
pub fn incoming(self) -> Incoming {
|
||||
Incoming::new(self)
|
||||
}
|
@ -17,13 +17,13 @@
|
||||
//! [incoming_method]: struct.TcpListener.html#method.incoming
|
||||
//! [`Incoming`]: struct.Incoming.html
|
||||
|
||||
#[cfg(feature = "async-traits")]
|
||||
mod incoming;
|
||||
mod listener;
|
||||
pub mod split;
|
||||
mod stream;
|
||||
|
||||
#[cfg(feature = "async-traits")]
|
||||
pub use self::incoming::Incoming;
|
||||
|
||||
mod listener;
|
||||
pub use self::listener::TcpListener;
|
||||
|
||||
pub mod split;
|
||||
|
||||
mod stream;
|
||||
pub use self::stream::TcpStream;
|
@ -1,6 +1,6 @@
|
||||
use super::split::{split, ReadHalf, WriteHalf};
|
||||
use crate::util::PollEvented;
|
||||
use crate::ToSocketAddrs;
|
||||
use crate::net::tcp::split::{split, ReadHalf, WriteHalf};
|
||||
use crate::net::util::PollEvented;
|
||||
use crate::net::ToSocketAddrs;
|
||||
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
||||
@ -8,7 +8,6 @@ use bytes::{Buf, BufMut};
|
||||
use futures_core::ready;
|
||||
use futures_util::future::poll_fn;
|
||||
use iovec::IoVec;
|
||||
use mio;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::io::{self, Read, Write};
|
@ -1,10 +1,9 @@
|
||||
use super::split::{split, UdpSocketRecvHalf, UdpSocketSendHalf};
|
||||
use crate::util::PollEvented;
|
||||
use crate::ToSocketAddrs;
|
||||
use crate::net::udp::split::{split, UdpSocketRecvHalf, UdpSocketSendHalf};
|
||||
use crate::net::util::PollEvented;
|
||||
use crate::net::ToSocketAddrs;
|
||||
|
||||
use futures_core::ready;
|
||||
use futures_util::future::poll_fn;
|
||||
use mio;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::io;
|
@ -1,8 +1,7 @@
|
||||
use crate::util::PollEvented;
|
||||
use crate::net::util::PollEvented;
|
||||
|
||||
use futures_core::ready;
|
||||
use futures_util::future::poll_fn;
|
||||
use mio_uds;
|
||||
use std::convert::TryFrom;
|
||||
use std::fmt;
|
||||
use std::io;
|
@ -1,5 +1,5 @@
|
||||
use super::UnixStream;
|
||||
use crate::util::PollEvented;
|
||||
use crate::net::unix::UnixStream;
|
||||
use crate::net::util::PollEvented;
|
||||
|
||||
use futures_core::ready;
|
||||
use futures_util::future::poll_fn;
|
@ -1,6 +1,6 @@
|
||||
use super::split::{split, ReadHalf, WriteHalf};
|
||||
use super::ucred::{self, UCred};
|
||||
use crate::util::PollEvented;
|
||||
use crate::net::unix::split::{split, ReadHalf, WriteHalf};
|
||||
use crate::net::unix::ucred::{self, UCred};
|
||||
use crate::net::util::PollEvented;
|
||||
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
@ -27,7 +27,7 @@ pub(crate) use self::impl_solaris::get_peer_cred;
|
||||
|
||||
#[cfg(any(target_os = "linux", target_os = "android"))]
|
||||
pub(crate) mod impl_linux {
|
||||
use crate::uds::UnixStream;
|
||||
use crate::net::unix::UnixStream;
|
||||
|
||||
use libc::{c_void, getsockopt, socklen_t, SOL_SOCKET, SO_PEERCRED};
|
||||
use std::{io, mem};
|
||||
@ -82,7 +82,7 @@ pub(crate) mod impl_linux {
|
||||
target_os = "openbsd"
|
||||
))]
|
||||
pub(crate) mod impl_macos {
|
||||
use crate::uds::UnixStream;
|
||||
use crate::net::unix::UnixStream;
|
||||
|
||||
use libc::getpeereid;
|
||||
use std::io;
|
||||
@ -152,35 +152,3 @@ pub(crate) mod impl_solaris {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Note that LOCAL_PEERCRED is not supported on DragonFly (yet). So do not run tests.
|
||||
#[cfg(not(target_os = "dragonfly"))]
|
||||
#[cfg(test)]
|
||||
mod test {
|
||||
use tokio::net::UnixStream;
|
||||
|
||||
use libc::getegid;
|
||||
use libc::geteuid;
|
||||
|
||||
#[tokio::test]
|
||||
#[cfg_attr(
|
||||
target_os = "freebsd",
|
||||
ignore = "Requires FreeBSD 12.0 or later. https://bugs.freebsd.org/bugzilla/show_bug.cgi?id=176419"
|
||||
)]
|
||||
#[cfg_attr(
|
||||
target_os = "netbsd",
|
||||
ignore = "NetBSD does not support getpeereid() for sockets created by socketpair()"
|
||||
)]
|
||||
async fn test_socket_pair() {
|
||||
let (a, b) = UnixStream::pair().unwrap();
|
||||
let cred_a = a.peer_cred().unwrap();
|
||||
let cred_b = b.peer_cred().unwrap();
|
||||
assert_eq!(cred_a, cred_b);
|
||||
|
||||
let uid = unsafe { geteuid() };
|
||||
let gid = unsafe { getegid() };
|
||||
|
||||
assert_eq!(cred_a.uid, uid);
|
||||
assert_eq!(cred_a.gid, gid);
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
//! Utilities for implementing networking types.
|
||||
|
||||
mod poll_evented;
|
||||
|
||||
pub use self::poll_evented::PollEvented;
|
@ -1,4 +1,4 @@
|
||||
use crate::driver::{platform, Registration};
|
||||
use crate::net::driver::{platform, Registration};
|
||||
|
||||
use tokio_io::{AsyncRead, AsyncWrite};
|
||||
|
||||
@ -55,7 +55,7 @@ use std::task::{Context, Poll};
|
||||
/// [`clear_read_ready`].
|
||||
///
|
||||
/// ```rust
|
||||
/// use tokio_net::util::PollEvented;
|
||||
/// use tokio::net::util::PollEvented;
|
||||
///
|
||||
/// use futures_core::ready;
|
||||
/// use mio::Ready;
|
@ -1,2 +0,0 @@
|
||||
//! An implementation of asynchronous process management for Tokio.
|
||||
pub use tokio_net::process::{Child, ChildStderr, ChildStdin, ChildStdout, Command};
|
@ -12,7 +12,7 @@
|
||||
//! for it complete.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use tokio_net::process::Command;
|
||||
//! use tokio::process::Command;
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
@ -35,7 +35,7 @@
|
||||
//! world` but we also capture its output.
|
||||
//!
|
||||
//! ```no_run
|
||||
//! use tokio_net::process::Command;
|
||||
//! use tokio::process::Command;
|
||||
//!
|
||||
//! #[tokio::main]
|
||||
//! async fn main() -> Result<(), Box<dyn std::error::Error>> {
|
||||
@ -102,9 +102,9 @@
|
||||
//! While similar to the standard library, this crate's `Child` type differs
|
||||
//! importantly in the behavior of `drop`. In the standard library, a child
|
||||
//! process will continue running after the instance of [`std::process::Child`]
|
||||
//! is dropped. In this crate, however, because [`tokio_net::process::Child`](crate::process::Child) is a
|
||||
//! is dropped. In this crate, however, because [`tokio::process::Child`](crate::process::Child) is a
|
||||
//! future of the child's `ExitStatus`, a child process is terminated if
|
||||
//! `tokio_net::process::Child` is dropped. The behavior of the standard library can
|
||||
//! `tokio::process::Child` is dropped. The behavior of the standard library can
|
||||
//! be regained with the [`Child::forget`](crate::process::Child::forget) method.
|
||||
|
||||
use std::ffi::OsStr;
|
||||
@ -178,7 +178,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
/// let command = Command::new("sh");
|
||||
/// ```
|
||||
pub fn new<S: AsRef<OsStr>>(program: S) -> Command {
|
||||
@ -192,18 +192,16 @@ impl Command {
|
||||
/// Only one argument can be passed per use. So instead of:
|
||||
///
|
||||
/// ```no_run
|
||||
/// # tokio_net::process::Command::new("sh")
|
||||
/// .arg("-C /path/to/repo")
|
||||
/// # ;
|
||||
/// tokio::process::Command::new("sh")
|
||||
/// .arg("-C /path/to/repo");
|
||||
/// ```
|
||||
///
|
||||
/// usage would be:
|
||||
///
|
||||
/// ```no_run
|
||||
/// # tokio_net::process::Command::new("sh")
|
||||
/// .arg("-C")
|
||||
/// .arg("/path/to/repo")
|
||||
/// # ;
|
||||
/// tokio::process::Command::new("sh")
|
||||
/// .arg("-C")
|
||||
/// .arg("/path/to/repo");
|
||||
/// ```
|
||||
///
|
||||
/// To pass multiple arguments see [`args`].
|
||||
@ -215,7 +213,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .arg("-l")
|
||||
@ -237,7 +235,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .args(&["-l", "-a"]);
|
||||
@ -261,7 +259,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .env("PATH", "/bin");
|
||||
@ -282,10 +280,10 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio::process::Command;
|
||||
/// use std::process::{Stdio};
|
||||
/// use std::env;
|
||||
/// use std::collections::HashMap;
|
||||
/// use tokio_net::process::Command;
|
||||
///
|
||||
/// let filtered_env : HashMap<String, String> =
|
||||
/// env::vars().filter(|&(ref k, _)|
|
||||
@ -315,7 +313,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .env_remove("PATH");
|
||||
@ -332,7 +330,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .env_clear();
|
||||
@ -357,7 +355,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .current_dir("/bin");
|
||||
@ -383,7 +381,7 @@ impl Command {
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::process::{Stdio};
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .stdin(Stdio::null());
|
||||
@ -406,8 +404,8 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use std::process::{Stdio};
|
||||
/// use tokio_net::process::Command;;
|
||||
/// use tokio::process::Command;;
|
||||
/// use std::process::Stdio;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .stdout(Stdio::null());
|
||||
@ -430,8 +428,8 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio::process::Command;;
|
||||
/// use std::process::{Stdio};
|
||||
/// use tokio_net::process::Command;;
|
||||
///
|
||||
/// let command = Command::new("ls")
|
||||
/// .stderr(Stdio::null());
|
||||
@ -525,7 +523,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// async fn run_ls() -> std::process::ExitStatus {
|
||||
/// Command::new("ls")
|
||||
@ -566,7 +564,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// async fn run_ls() -> std::process::ExitStatus {
|
||||
/// Command::new("ls")
|
||||
@ -617,7 +615,7 @@ impl Command {
|
||||
/// Basic usage:
|
||||
///
|
||||
/// ```no_run
|
||||
/// use tokio_net::process::Command;
|
||||
/// use tokio::process::Command;
|
||||
///
|
||||
/// async fn run_ls() {
|
||||
/// let output: std::process::Output = Command::new("ls")
|
||||
@ -705,7 +703,7 @@ impl<T: TryFuture + Kill + Unpin> Future for ChildDropGuard<T> {
|
||||
/// like the OS-assigned identifier and the stdio streams.
|
||||
///
|
||||
/// > **Note**: The behavior of `drop` on a child in this crate is *different
|
||||
/// > than the behavior of the standard library*. If a `tokio_net::process::Child` is
|
||||
/// > than the behavior of the standard library*. If a `tokio::process::Child` is
|
||||
/// > dropped before the process finishes then the process will be terminated.
|
||||
/// > In the standard library, however, the process continues executing. This is
|
||||
/// > done because futures in general take `drop` as a sign of cancellation, and
|
||||
@ -800,7 +798,7 @@ impl Child {
|
||||
/// > `Child` instance into an event loop as an alternative to this method.
|
||||
///
|
||||
/// ```no_run
|
||||
/// # use tokio_net::process::Command;
|
||||
/// # use tokio::process::Command;
|
||||
///
|
||||
/// # #[tokio::main]
|
||||
/// # async fn main() {
|
@ -27,9 +27,9 @@ mod reap;
|
||||
use self::orphan::{AtomicOrphanQueue, OrphanQueue, Wait};
|
||||
use self::reap::Reaper;
|
||||
use super::SpawnedChild;
|
||||
use crate::net::util::PollEvented;
|
||||
use crate::process::kill::Kill;
|
||||
use crate::signal::unix::{signal, Signal, SignalKind};
|
||||
use crate::util::PollEvented;
|
||||
use mio::event::Evented;
|
||||
use mio::unix::{EventedFd, UnixReady};
|
||||
use mio::{Poll as MioPoll, PollOpt, Ready, Token};
|
@ -15,9 +15,11 @@
|
||||
//! `RegisterWaitForSingleObject` and then wait on the other end of the oneshot
|
||||
//! from then on out.
|
||||
|
||||
use super::SpawnedChild;
|
||||
use crate::net::util::PollEvented;
|
||||
use crate::process::kill::Kill;
|
||||
use crate::util::PollEvented;
|
||||
use crate::process::SpawnedChild;
|
||||
use crate::sync::oneshot;
|
||||
|
||||
use futures_util::future::Fuse;
|
||||
use futures_util::future::FutureExt;
|
||||
use mio_named_pipes::NamedPipe;
|
||||
@ -31,7 +33,6 @@ use std::process::{Child as StdChild, Command as StdCommand, ExitStatus};
|
||||
use std::ptr;
|
||||
use std::task::Context;
|
||||
use std::task::Poll;
|
||||
use tokio_sync::oneshot;
|
||||
use winapi::shared::minwindef::FALSE;
|
||||
use winapi::shared::winerror::WAIT_TIMEOUT;
|
||||
use winapi::um::handleapi::INVALID_HANDLE_VALUE;
|
@ -1,9 +1,9 @@
|
||||
use crate::net::driver::Reactor;
|
||||
use crate::runtime::current_thread::Runtime;
|
||||
use crate::timer::clock::Clock;
|
||||
use crate::timer::timer::Timer;
|
||||
|
||||
use tokio_executor::current_thread::CurrentThread;
|
||||
use tokio_net::driver::Reactor;
|
||||
|
||||
use std::io;
|
||||
|
||||
|
@ -1,10 +1,10 @@
|
||||
use crate::net::driver::{self, Reactor};
|
||||
use crate::runtime::current_thread::Builder;
|
||||
use crate::timer::clock::{self, Clock};
|
||||
use crate::timer::timer::{self, Timer};
|
||||
|
||||
use tokio_executor::current_thread::Handle as ExecutorHandle;
|
||||
use tokio_executor::current_thread::{self, CurrentThread};
|
||||
use tokio_net::driver::{self, Reactor};
|
||||
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
|
@ -119,7 +119,7 @@
|
||||
//! }
|
||||
//! ```
|
||||
//!
|
||||
//! [driver]: tokio_net::driver
|
||||
//! [driver]: tokio::net::driver
|
||||
//! [executor]: https://tokio.rs/docs/internals/runtime-model/#executors
|
||||
//! [timer]: ../timer/index.html
|
||||
//! [`Runtime`]: struct.Runtime.html
|
||||
|
@ -1,9 +1,9 @@
|
||||
use super::{Inner, Runtime};
|
||||
use crate::net::driver::{self, Reactor};
|
||||
use crate::runtime::threadpool::{Inner, Runtime};
|
||||
use crate::timer::clock::{self, Clock};
|
||||
use crate::timer::timer::{self, Timer};
|
||||
|
||||
use tokio_executor::thread_pool;
|
||||
use tokio_net::driver::{self, Reactor};
|
||||
|
||||
use std::sync::{Arc, Mutex};
|
||||
use std::{fmt, io};
|
||||
|
@ -9,10 +9,10 @@ pub use self::spawner::Spawner;
|
||||
#[allow(unreachable_pub)] // https://github.com/rust-lang/rust/issues/57411
|
||||
pub use tokio_executor::thread_pool::JoinHandle;
|
||||
|
||||
use crate::net::driver;
|
||||
use crate::timer::timer;
|
||||
|
||||
use tokio_executor::thread_pool::ThreadPool;
|
||||
use tokio_net::driver;
|
||||
|
||||
use std::future::Future;
|
||||
use std::io;
|
||||
@ -42,7 +42,7 @@ struct Inner {
|
||||
pool: ThreadPool,
|
||||
|
||||
/// Reactor handles
|
||||
reactor_handles: Vec<tokio_net::driver::Handle>,
|
||||
reactor_handles: Vec<crate::net::driver::Handle>,
|
||||
|
||||
/// Timer handles
|
||||
timer_handles: Vec<timer::Handle>,
|
||||
|
@ -1,4 +0,0 @@
|
||||
//! Asynchronous signal handling for `tokio`. ctrl-C notifications are
|
||||
//! supported on both unix and windows systems. For finer grained signal
|
||||
//! handling support on unix systems, see `tokio_net::signal::unix::Signal`.
|
||||
pub use tokio_net::signal::ctrl_c;
|
@ -17,7 +17,7 @@
|
||||
//! Print out all ctrl-C notifications received
|
||||
//!
|
||||
//! ```rust,no_run
|
||||
//! use tokio_net::signal;
|
||||
//! use tokio::signal;
|
||||
//!
|
||||
//! use futures_util::future;
|
||||
//! use futures_util::stream::StreamExt;
|
||||
@ -45,7 +45,7 @@
|
||||
//! ```rust,no_run
|
||||
//! # #[cfg(unix)] {
|
||||
//!
|
||||
//! use tokio_net::signal::{self, unix::{signal, SignalKind}};
|
||||
//! use tokio::signal::{self, unix::{signal, SignalKind}};
|
||||
//!
|
||||
//! use futures_util::future;
|
||||
//! use futures_util::stream::StreamExt;
|
||||
@ -82,6 +82,7 @@ mod registry;
|
||||
mod os {
|
||||
#[cfg(unix)]
|
||||
pub(crate) use super::unix::{OsExtraData, OsStorage};
|
||||
|
||||
#[cfg(windows)]
|
||||
pub(crate) use super::windows::{OsExtraData, OsStorage};
|
||||
}
|
@ -1,4 +1,4 @@
|
||||
use super::os::{OsExtraData, OsStorage};
|
||||
use crate::signal::os::{OsExtraData, OsStorage};
|
||||
|
||||
use tokio_sync::mpsc::Sender;
|
||||
|
||||
@ -178,56 +178,59 @@ where
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use futures_util::{future, StreamExt};
|
||||
use tokio_sync::mpsc::channel;
|
||||
use tokio_sync::oneshot;
|
||||
use crate::runtime::current_thread::Runtime;
|
||||
use crate::sync::{mpsc, oneshot};
|
||||
use futures::{future, StreamExt};
|
||||
|
||||
#[tokio::test]
|
||||
async fn smoke() {
|
||||
let registry = Registry::new(vec![
|
||||
EventInfo::default(),
|
||||
EventInfo::default(),
|
||||
EventInfo::default(),
|
||||
]);
|
||||
#[test]
|
||||
fn smoke() {
|
||||
let mut rt = Runtime::new().unwrap();
|
||||
rt.block_on(async move {
|
||||
let registry = Registry::new(vec![
|
||||
EventInfo::default(),
|
||||
EventInfo::default(),
|
||||
EventInfo::default(),
|
||||
]);
|
||||
|
||||
let (first_tx, first_rx) = channel(3);
|
||||
let (second_tx, second_rx) = channel(3);
|
||||
let (third_tx, third_rx) = channel(3);
|
||||
let (first_tx, first_rx) = mpsc::channel(3);
|
||||
let (second_tx, second_rx) = mpsc::channel(3);
|
||||
let (third_tx, third_rx) = mpsc::channel(3);
|
||||
|
||||
registry.register_listener(0, first_tx);
|
||||
registry.register_listener(1, second_tx);
|
||||
registry.register_listener(2, third_tx);
|
||||
registry.register_listener(0, first_tx);
|
||||
registry.register_listener(1, second_tx);
|
||||
registry.register_listener(2, third_tx);
|
||||
|
||||
let (fire, wait) = oneshot::channel();
|
||||
let (fire, wait) = oneshot::channel();
|
||||
|
||||
tokio::spawn(async {
|
||||
wait.await.expect("wait failed");
|
||||
crate::spawn(async {
|
||||
wait.await.expect("wait failed");
|
||||
|
||||
// Record some events which should get coalesced
|
||||
registry.record_event(0);
|
||||
registry.record_event(0);
|
||||
registry.record_event(1);
|
||||
registry.record_event(1);
|
||||
registry.broadcast();
|
||||
// Record some events which should get coalesced
|
||||
registry.record_event(0);
|
||||
registry.record_event(0);
|
||||
registry.record_event(1);
|
||||
registry.record_event(1);
|
||||
registry.broadcast();
|
||||
|
||||
// Send subsequent signal
|
||||
registry.record_event(0);
|
||||
registry.broadcast();
|
||||
// Send subsequent signal
|
||||
registry.record_event(0);
|
||||
registry.broadcast();
|
||||
|
||||
drop(registry);
|
||||
drop(registry);
|
||||
});
|
||||
|
||||
let _ = fire.send(());
|
||||
let all = future::join3(
|
||||
first_rx.collect::<Vec<_>>(),
|
||||
second_rx.collect::<Vec<_>>(),
|
||||
third_rx.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let (first_results, second_results, third_results) = all.await;
|
||||
assert_eq!(2, first_results.len());
|
||||
assert_eq!(1, second_results.len());
|
||||
assert_eq!(0, third_results.len());
|
||||
});
|
||||
|
||||
let _ = fire.send(());
|
||||
let all = future::join3(
|
||||
first_rx.collect::<Vec<_>>(),
|
||||
second_rx.collect::<Vec<_>>(),
|
||||
third_rx.collect::<Vec<_>>(),
|
||||
);
|
||||
|
||||
let (first_results, second_results, third_results) = all.await;
|
||||
assert_eq!(2, first_results.len());
|
||||
assert_eq!(1, second_results.len());
|
||||
assert_eq!(0, third_results.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -235,7 +238,7 @@ mod tests {
|
||||
fn register_panics_on_invalid_input() {
|
||||
let registry = Registry::new(vec![EventInfo::default()]);
|
||||
|
||||
let (tx, _) = channel(1);
|
||||
let (tx, _) = mpsc::channel(1);
|
||||
registry.register_listener(1, tx);
|
||||
}
|
||||
|
||||
@ -245,37 +248,41 @@ mod tests {
|
||||
registry.record_event(42);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn broadcast_cleans_up_disconnected_listeners() {
|
||||
let registry = Registry::new(vec![EventInfo::default()]);
|
||||
#[test]
|
||||
fn broadcast_cleans_up_disconnected_listeners() {
|
||||
let mut rt = Runtime::new().unwrap();
|
||||
|
||||
let (first_tx, first_rx) = channel(1);
|
||||
let (second_tx, second_rx) = channel(1);
|
||||
let (third_tx, third_rx) = channel(1);
|
||||
rt.block_on(async {
|
||||
let registry = Registry::new(vec![EventInfo::default()]);
|
||||
|
||||
registry.register_listener(0, first_tx);
|
||||
registry.register_listener(0, second_tx);
|
||||
registry.register_listener(0, third_tx);
|
||||
let (first_tx, first_rx) = mpsc::channel(1);
|
||||
let (second_tx, second_rx) = mpsc::channel(1);
|
||||
let (third_tx, third_rx) = mpsc::channel(1);
|
||||
|
||||
drop(first_rx);
|
||||
drop(second_rx);
|
||||
registry.register_listener(0, first_tx);
|
||||
registry.register_listener(0, second_tx);
|
||||
registry.register_listener(0, third_tx);
|
||||
|
||||
let (fire, wait) = oneshot::channel();
|
||||
drop(first_rx);
|
||||
drop(second_rx);
|
||||
|
||||
tokio::spawn(async {
|
||||
wait.await.expect("wait failed");
|
||||
let (fire, wait) = oneshot::channel();
|
||||
|
||||
registry.record_event(0);
|
||||
registry.broadcast();
|
||||
crate::spawn(async {
|
||||
wait.await.expect("wait failed");
|
||||
|
||||
assert_eq!(1, registry.storage[0].recipients.lock().unwrap().len());
|
||||
drop(registry);
|
||||
registry.record_event(0);
|
||||
registry.broadcast();
|
||||
|
||||
assert_eq!(1, registry.storage[0].recipients.lock().unwrap().len());
|
||||
drop(registry);
|
||||
});
|
||||
|
||||
let _ = fire.send(());
|
||||
let results: Vec<()> = third_rx.collect().await;
|
||||
|
||||
assert_eq!(1, results.len());
|
||||
});
|
||||
|
||||
let _ = fire.send(());
|
||||
let results: Vec<()> = third_rx.collect().await;
|
||||
|
||||
assert_eq!(1, results.len());
|
||||
}
|
||||
|
||||
#[test]
|
||||
@ -285,8 +292,8 @@ mod tests {
|
||||
registry.record_event(0);
|
||||
assert_eq!(false, registry.broadcast());
|
||||
|
||||
let (first_tx, first_rx) = channel(1);
|
||||
let (second_tx, second_rx) = channel(1);
|
||||
let (first_tx, first_rx) = mpsc::channel(1);
|
||||
let (second_tx, second_rx) = mpsc::channel(1);
|
||||
|
||||
registry.register_listener(0, first_tx);
|
||||
registry.register_listener(0, second_tx);
|
@ -6,13 +6,11 @@
|
||||
#![cfg(unix)]
|
||||
|
||||
use super::registry::{globals, EventId, EventInfo, Globals, Init, Storage};
|
||||
use crate::util::PollEvented;
|
||||
use crate::net::util::PollEvented;
|
||||
|
||||
use tokio_io::AsyncRead;
|
||||
use tokio_sync::mpsc::{channel, Receiver};
|
||||
|
||||
pub use libc;
|
||||
|
||||
use futures_core::stream::Stream;
|
||||
use libc::c_int;
|
||||
use mio_uds::UnixStream;
|
||||
@ -72,7 +70,7 @@ impl SignalKind {
|
||||
/// For example, this can be used for listening for platform-specific
|
||||
/// signals.
|
||||
/// ```rust,no_run
|
||||
/// # use tokio_net::signal::unix::SignalKind;
|
||||
/// # use tokio::signal::unix::SignalKind;
|
||||
/// # let signum = -1;
|
||||
/// // let signum = libc::OS_SPECIFIC_SIGNAL;
|
||||
/// let kind = SignalKind::from_raw(signum);
|
@ -175,43 +175,43 @@ impl Stream for CtrlBreak {
|
||||
#[cfg(test)]
|
||||
mod tests {
|
||||
use super::*;
|
||||
use crate::runtime::current_thread::Runtime;
|
||||
|
||||
use tokio::timer::Timeout;
|
||||
|
||||
use futures_util::future::FutureExt;
|
||||
use futures_util::stream::StreamExt;
|
||||
use std::future::Future;
|
||||
use std::time::Duration;
|
||||
|
||||
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"))
|
||||
#[test]
|
||||
fn ctrl_c() {
|
||||
let mut rt = Runtime::new().unwrap();
|
||||
|
||||
rt.block_on(async {
|
||||
let ctrl_c = crate::signal::ctrl_c().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
|
||||
// integration and test that our handling works.
|
||||
unsafe {
|
||||
super::handler(CTRL_C_EVENT);
|
||||
}
|
||||
|
||||
let _ = ctrl_c.into_future().await;
|
||||
});
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn ctrl_c() {
|
||||
let ctrl_c = crate::signal::ctrl_c().expect("failed to create CtrlC");
|
||||
#[test]
|
||||
fn ctrl_break() {
|
||||
let mut rt = Runtime::new().unwrap();
|
||||
|
||||
// Windows doesn't have a good programmatic way of sending events
|
||||
// like sending signals on Unix, so we'll stub out the actual OS
|
||||
// integration and test that our handling works.
|
||||
unsafe {
|
||||
super::handler(CTRL_C_EVENT);
|
||||
}
|
||||
rt.block_on(async {
|
||||
let ctrl_break = super::ctrl_break().expect("failed to create CtrlC");
|
||||
|
||||
let _ = with_timeout(ctrl_c.into_future()).await;
|
||||
}
|
||||
// Windows doesn't have a good programmatic way of sending events
|
||||
// like sending signals on Unix, so we'll stub out the actual OS
|
||||
// integration and test that our handling works.
|
||||
unsafe {
|
||||
super::handler(CTRL_BREAK_EVENT);
|
||||
}
|
||||
|
||||
#[tokio::test]
|
||||
async fn ctrl_break() {
|
||||
let ctrl_break = super::ctrl_break().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
|
||||
// integration and test that our handling works.
|
||||
unsafe {
|
||||
super::handler(CTRL_BREAK_EVENT);
|
||||
}
|
||||
|
||||
let _ = with_timeout(ctrl_break.into_future()).await;
|
||||
let _ = ctrl_break.into_future().await;
|
||||
});
|
||||
}
|
||||
}
|
@ -1,5 +1,4 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(feature = "default")]
|
||||
|
||||
use tokio::net::TcpListener;
|
||||
use tokio::prelude::*;
|
||||
|
@ -1,12 +1,7 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
|
||||
mod support;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
use std::convert::TryFrom;
|
||||
use std::net;
|
||||
use support::*;
|
||||
use tokio::net::TcpListener;
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
@ -14,9 +9,3 @@ fn no_runtime_panics_binding_net_tcp_listener() {
|
||||
let listener = net::TcpListener::bind("127.0.0.1:0").expect("failed to bind listener");
|
||||
let _ = TcpListener::try_from(listener);
|
||||
}
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn no_runtime_panics_creating_signals() {
|
||||
let _ = signal(SignalKind::hangup());
|
||||
}
|
@ -1,8 +1,7 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(feature = "default")]
|
||||
|
||||
use tokio_net::driver::Reactor;
|
||||
use tokio_net::tcp::TcpListener;
|
||||
use tokio::net::driver::Reactor;
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_test::{assert_ok, assert_pending};
|
||||
|
||||
use futures_util::task::{waker_ref, ArcWake};
|
||||
@ -66,7 +65,7 @@ fn test_drop_on_notify() {
|
||||
|
||||
{
|
||||
let handle = reactor.handle();
|
||||
let _reactor = tokio_net::driver::set_default(&handle);
|
||||
let _reactor = tokio::net::driver::set_default(&handle);
|
||||
let waker = waker_ref(&task);
|
||||
let mut cx = Context::from_waker(&waker);
|
||||
assert_pending!(task.future.lock().unwrap().as_mut().poll(&mut cx));
|
@ -1,8 +1,7 @@
|
||||
#![warn(rust_2018_idioms)]
|
||||
#![cfg(feature = "default")]
|
||||
|
||||
use tokio::net::driver::{self, Reactor};
|
||||
use tokio::net::TcpListener;
|
||||
use tokio_net::driver::{self, Reactor};
|
||||
use tokio_test::{assert_err, assert_pending, assert_ready, task};
|
||||
|
||||
#[test]
|
@ -2,6 +2,9 @@
|
||||
#![cfg(unix)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use tokio::process::Command;
|
||||
use tokio::runtime::current_thread;
|
||||
|
||||
use futures_util::future::FutureExt;
|
||||
use futures_util::stream::FuturesOrdered;
|
||||
use std::process::Stdio;
|
||||
@ -9,11 +12,6 @@ use std::sync::atomic::{AtomicBool, Ordering};
|
||||
use std::sync::Arc;
|
||||
use std::thread;
|
||||
use std::time::Duration;
|
||||
use tokio::runtime::current_thread;
|
||||
use tokio_net::process::Command;
|
||||
|
||||
mod support;
|
||||
use support::*;
|
||||
|
||||
fn run_test() {
|
||||
let finished = Arc::new(AtomicBool::new(false));
|
||||
@ -22,7 +20,7 @@ fn run_test() {
|
||||
thread::spawn(move || {
|
||||
let mut rt = current_thread::Runtime::new().expect("failed to get runtime");
|
||||
let mut futures = FuturesOrdered::new();
|
||||
run_with_timeout(&mut rt, async {
|
||||
rt.block_on(async {
|
||||
for i in 0..2 {
|
||||
futures.push(
|
||||
Command::new("echo")
|
||||
@ -36,6 +34,7 @@ fn run_test() {
|
||||
)
|
||||
}
|
||||
});
|
||||
|
||||
drop(rt);
|
||||
finished_clone.store(true, Ordering::SeqCst);
|
||||
});
|
@ -1,10 +1,8 @@
|
||||
#![cfg(feature = "process")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use tokio_net::process::Command;
|
||||
|
||||
mod support;
|
||||
use support::*;
|
||||
use tokio::process::Command;
|
||||
use tokio_test::assert_ok;
|
||||
|
||||
#[tokio::test]
|
||||
async fn simple() {
|
||||
@ -23,9 +21,7 @@ async fn simple() {
|
||||
let id = child.id();
|
||||
assert!(id > 0);
|
||||
|
||||
let status = with_timeout(&mut child)
|
||||
.await
|
||||
.expect("failed to run future");
|
||||
let status = assert_ok!((&mut child).await);
|
||||
assert_eq!(status.code(), Some(2));
|
||||
|
||||
assert_eq!(child.id(), id);
|
28
tokio/tests/signal_ctrl_c.rs
Normal file
28
tokio/tests/signal_ctrl_c.rs
Normal file
@ -0,0 +1,28 @@
|
||||
#![cfg(unix)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod support {
|
||||
pub mod signal;
|
||||
}
|
||||
use support::signal::send_signal;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::signal;
|
||||
use tokio::sync::oneshot;
|
||||
|
||||
#[tokio::test]
|
||||
async fn ctrl_c() {
|
||||
let ctrl_c = signal::ctrl_c().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 _ = ctrl_c.into_future().await;
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod support;
|
||||
use support::*;
|
||||
mod support {
|
||||
pub mod signal;
|
||||
}
|
||||
use support::signal::send_signal;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
#[tokio::test]
|
||||
async fn drop_then_get_a_signal() {
|
||||
@ -14,5 +18,5 @@ async fn drop_then_get_a_signal() {
|
||||
send_signal(libc::SIGUSR1);
|
||||
let sig = signal(kind).expect("failed to create second signal");
|
||||
|
||||
let _ = with_timeout(sig.into_future()).await;
|
||||
let _ = sig.into_future().await;
|
||||
}
|
@ -1,31 +1,37 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
pub mod support;
|
||||
use support::*;
|
||||
mod support {
|
||||
pub mod signal;
|
||||
}
|
||||
use support::signal::send_signal;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::runtime::current_thread::Runtime;
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
#[test]
|
||||
fn dropping_loops_does_not_cause_starvation() {
|
||||
let kind = SignalKind::user_defined1();
|
||||
|
||||
let mut first_rt = CurrentThreadRuntime::new().expect("failed to init first runtime");
|
||||
let mut first_rt = Runtime::new().expect("failed to init first runtime");
|
||||
let mut first_signal =
|
||||
first_rt.block_on(async { signal(kind).expect("failed to register first signal") });
|
||||
|
||||
let mut second_rt = CurrentThreadRuntime::new().expect("failed to init second runtime");
|
||||
let mut second_rt = Runtime::new().expect("failed to init second runtime");
|
||||
let mut second_signal =
|
||||
second_rt.block_on(async { signal(kind).expect("failed to register second signal") });
|
||||
|
||||
send_signal(libc::SIGUSR1);
|
||||
|
||||
let _ =
|
||||
run_with_timeout(&mut first_rt, first_signal.next()).expect("failed to await first signal");
|
||||
first_rt
|
||||
.block_on(first_signal.next())
|
||||
.expect("failed to await first signal");
|
||||
|
||||
drop(first_rt);
|
||||
drop(first_signal);
|
||||
|
||||
send_signal(libc::SIGUSR1);
|
||||
|
||||
let _ = run_with_timeout(&mut second_rt, second_signal.next());
|
||||
second_rt.block_on(second_signal.next());
|
||||
}
|
@ -1,16 +1,19 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
pub mod support;
|
||||
use support::*;
|
||||
mod support {
|
||||
pub mod signal;
|
||||
}
|
||||
use support::signal::send_signal;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
#[tokio::test]
|
||||
async fn dropping_signal_does_not_deregister_any_other_instances() {
|
||||
let kind = SignalKind::user_defined1();
|
||||
|
||||
// NB: Testing for issue alexcrichton/tokio-signal#38:
|
||||
// signals should not starve based on ordering
|
||||
// Signals should not starve based on ordering
|
||||
let first_duplicate_signal = signal(kind).expect("failed to register first duplicate signal");
|
||||
let sig = signal(kind).expect("failed to register signal");
|
||||
let second_duplicate_signal = signal(kind).expect("failed to register second duplicate signal");
|
||||
@ -19,5 +22,5 @@ async fn dropping_signal_does_not_deregister_any_other_instances() {
|
||||
drop(second_duplicate_signal);
|
||||
|
||||
send_signal(libc::SIGUSR1);
|
||||
let _ = with_timeout(sig.into_future()).await;
|
||||
let _ = sig.into_future().await;
|
||||
}
|
@ -1,9 +1,14 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod support;
|
||||
use support::*;
|
||||
mod support {
|
||||
pub mod signal;
|
||||
}
|
||||
use support::signal::send_signal;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::runtime::current_thread::Runtime;
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
use std::sync::mpsc::channel;
|
||||
use std::thread;
|
||||
@ -19,8 +24,8 @@ fn multi_loop() {
|
||||
.map(|_| {
|
||||
let sender = sender.clone();
|
||||
thread::spawn(move || {
|
||||
let mut rt = CurrentThreadRuntime::new().unwrap();
|
||||
let _ = run_with_timeout(&mut rt, async {
|
||||
let mut rt = Runtime::new().unwrap();
|
||||
let _ = rt.block_on(async {
|
||||
let signal = signal(SignalKind::hangup()).unwrap();
|
||||
sender.send(()).unwrap();
|
||||
signal.into_future().await
|
10
tokio/tests/signal_no_rt.rs
Normal file
10
tokio/tests/signal_no_rt.rs
Normal file
@ -0,0 +1,10 @@
|
||||
#![cfg(unix)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
#[test]
|
||||
#[should_panic]
|
||||
fn no_runtime_panics_creating_signals() {
|
||||
let _ = signal(SignalKind::hangup());
|
||||
}
|
@ -1,9 +1,15 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod support;
|
||||
use support::*;
|
||||
mod support {
|
||||
pub mod signal;
|
||||
}
|
||||
use support::signal::send_signal;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
use futures::future;
|
||||
|
||||
#[tokio::test]
|
||||
async fn notify_both() {
|
||||
@ -13,5 +19,5 @@ async fn notify_both() {
|
||||
let signal2 = signal(kind).expect("failed to create signal2");
|
||||
|
||||
send_signal(libc::SIGUSR2);
|
||||
let _ = with_timeout(future::join(signal1.into_future(), signal2.into_future())).await;
|
||||
let _ = future::join(signal1.into_future(), signal2.into_future()).await;
|
||||
}
|
@ -1,9 +1,13 @@
|
||||
#![cfg(unix)]
|
||||
#![cfg(feature = "signal")]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod support;
|
||||
use support::*;
|
||||
mod support {
|
||||
pub mod signal;
|
||||
}
|
||||
use support::signal::send_signal;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
|
||||
#[tokio::test]
|
||||
async fn twice() {
|
||||
@ -13,7 +17,7 @@ async fn twice() {
|
||||
for _ in 0..2 {
|
||||
send_signal(libc::SIGUSR1);
|
||||
|
||||
let (item, sig_next) = with_timeout(sig.into_future()).await;
|
||||
let (item, sig_next) = sig.into_future().await;
|
||||
assert_eq!(item, Some(()));
|
||||
|
||||
sig = sig_next;
|
23
tokio/tests/signal_usr1.rs
Normal file
23
tokio/tests/signal_usr1.rs
Normal file
@ -0,0 +1,23 @@
|
||||
#![cfg(unix)]
|
||||
#![warn(rust_2018_idioms)]
|
||||
|
||||
mod support {
|
||||
pub mod signal;
|
||||
}
|
||||
use support::signal::send_signal;
|
||||
|
||||
use tokio::prelude::*;
|
||||
use tokio::signal::unix::{signal, SignalKind};
|
||||
use tokio_test::assert_ok;
|
||||
|
||||
#[tokio::test]
|
||||
async fn signal_usr1() {
|
||||
let signal = assert_ok!(
|
||||
signal(SignalKind::user_defined1()),
|
||||
"failed to create signal"
|
||||
);
|
||||
|
||||
send_signal(libc::SIGUSR1);
|
||||
|
||||
let _ = signal.into_future().await;
|
||||
}
|
7
tokio/tests/support/signal.rs
Normal file
7
tokio/tests/support/signal.rs
Normal file
@ -0,0 +1,7 @@
|
||||
pub fn send_signal(signal: libc::c_int) {
|
||||
use libc::{getpid, kill};
|
||||
|
||||
unsafe {
|
||||
assert_eq!(kill(getpid(), signal), 0);
|
||||
}
|
||||
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user