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:
Carl Lerche 2019-10-25 12:50:15 -07:00 committed by GitHub
parent 03a9378297
commit 227533d456
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
111 changed files with 578 additions and 868 deletions

View File

@ -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",
]

View File

@ -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

View File

@ -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"

View File

@ -1,3 +0,0 @@
use build_tests::tokio_executor::current_thread;
fn main() {}

View File

@ -1,4 +0,0 @@
use build_tests::tokio_net::tcp;
fn main() {}

View File

@ -1,4 +0,0 @@
use build_tests::tokio_net::udp;
fn main() {}

View File

@ -1,4 +0,0 @@
use build_tests::tokio_net::uds;
fn main() {}

View File

@ -1,3 +0,0 @@
use build_tests::tokio::net;
fn main() {}

View File

@ -1,5 +1,5 @@
jobs:
- job: loom
- job: ${{ parameters.name }}
displayName: Loom tests
pool:
vmImage: ubuntu-16.04

View File

@ -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
View 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"

View File

@ -0,0 +1,3 @@
use tests_build::tokio_executor::current_thread;
fn main() {}

View File

@ -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`.

View File

@ -1,4 +1,4 @@
use build_tests::tokio;
use tests_build::tokio;
#[tokio::main]
fn main_is_not_async() {}

View File

@ -0,0 +1,4 @@
use tests_build::tokio_net::tcp;
fn main() {}

View File

@ -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`.

View File

@ -0,0 +1,4 @@
use tests_build::tokio_net::udp;
fn main() {}

View File

@ -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`.

View File

@ -0,0 +1,4 @@
use tests_build::tokio_net::uds;
fn main() {}

View File

@ -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`.

View File

@ -0,0 +1,3 @@
use tests_build::tokio::net;
fn main() {}

View File

@ -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`.

View File

@ -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]

View 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"] }

View File

@ -0,0 +1 @@
Tests that require additional components than just the `tokio` crate.

View File

@ -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);
}

View File

@ -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;

View File

@ -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

View File

@ -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

View File

@ -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.

View File

@ -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.

View File

@ -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;

View File

@ -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;
}

View File

@ -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);
}
}

View File

@ -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 }

View File

@ -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"

View File

@ -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;

View File

@ -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};

View File

@ -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;

View File

@ -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();

View File

@ -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
View 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};

View File

@ -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;

View File

@ -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)
}

View File

@ -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;

View File

@ -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};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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};

View File

@ -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);
}
}

View File

@ -1,5 +1,4 @@
//! Utilities for implementing networking types.
mod poll_evented;
pub use self::poll_evented::PollEvented;

View File

@ -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;

View File

@ -1,2 +0,0 @@
//! An implementation of asynchronous process management for Tokio.
pub use tokio_net::process::{Child, ChildStderr, ChildStdin, ChildStdout, Command};

View File

@ -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() {

View File

@ -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};

View File

@ -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;

View File

@ -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;

View File

@ -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;

View File

@ -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

View File

@ -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};

View File

@ -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>,

View File

@ -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;

View File

@ -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};
}

View File

@ -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);

View File

@ -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);

View File

@ -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;
});
}
}

View File

@ -1,5 +1,4 @@
#![warn(rust_2018_idioms)]
#![cfg(feature = "default")]
use tokio::net::TcpListener;
use tokio::prelude::*;

View File

@ -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());
}

View File

@ -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));

View File

@ -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]

View File

@ -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);
});

View File

@ -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);

View 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;
}

View File

@ -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;
}

View File

@ -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());
}

View File

@ -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;
}

View File

@ -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

View 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());
}

View File

@ -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;
}

View File

@ -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;

View 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;
}

View 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