executor: move current-thread into crate (#1447)

The `CurrentThread` executor is exposed using a feature flag.

Refs: #1264
This commit is contained in:
Carl Lerche 2019-08-15 09:52:25 -07:00 committed by GitHub
parent 8d55f98f6f
commit 9de7083be8
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
25 changed files with 110 additions and 174 deletions

View File

@ -4,7 +4,6 @@ members = [
"tokio",
"tokio-buf",
"tokio-codec",
"tokio-current-thread",
"tokio-executor",
"tokio-fs",
"tokio-io",
@ -20,4 +19,5 @@ members = [
"tokio-tls",
"tokio-udp",
"tokio-uds",
"ui-tests",
]

View File

@ -66,8 +66,8 @@ jobs:
crates:
tokio-buf: []
tokio-codec: []
tokio-current-thread: []
tokio-executor: []
tokio-executor:
- current-thread
tokio-io:
- util
tokio-sync:
@ -78,6 +78,16 @@ jobs:
- async-traits
tokio-test: []
# Test compilation failure
- template: ci/azure-test-stable.yml
parameters:
name: test_features
displayName: Test feature flags
rust: $(nightly)
crates:
ui-tests:
- executor-without-current-thread
# - template: ci/azure-cargo-check.yml
# parameters:
# name: features

View File

@ -4,7 +4,6 @@
tokio = { path = "tokio" }
tokio-buf = { path = "tokio-buf" }
tokio-codec = { path = "tokio-codec" }
tokio-current-thread = { path = "tokio-current-thread" }
tokio-executor = { path = "tokio-executor" }
tokio-fs = { path = "tokio-fs" }
tokio-io = { path = "tokio-io" }

View File

@ -1,36 +0,0 @@
# 0.2.0-alpha.1 (August 8, 2019)
### Changed
- Switch to `async`, `await`, and `std::future`.
# 0.1.6 (March 22, 2019)
### Added
- implement `TypedExecutor` (#993).
# 0.1.5 (March 1, 2019)
### Fixed
- Documentation typos (#882).
# 0.1.4 (November 21, 2018)
* Fix shutdown on idle (#763).
# 0.1.3 (September 27, 2018)
* Fix minimal versions
# 0.1.2 (September 26, 2018)
* Implement `futures::Executor` for executor types (#563)
* Spawning performance improvements (#565)
# 0.1.1 (August 6, 2018)
* Implement `std::Error` for misc error types (#501)
* bugfix: Track tasks pending in spawn queue (#478)
# 0.1.0 (June 13, 2018)
* Extract `tokio::executor::current_thread` to a tokio-current-thread crate (#356)

View File

@ -1,28 +0,0 @@
[package]
name = "tokio-current-thread"
# 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.1"
edition = "2018"
authors = ["Tokio Contributors <team@tokio.rs>"]
license = "MIT"
repository = "https://github.com/tokio-rs/tokio"
homepage = "https://tokio.rs"
documentation = "https://docs.rs/tokio-current-thread/0.2.0-alpha.1/tokio_current_thread"
description = """
Single threaded executor which manage many tasks concurrently on the current thread.
"""
keywords = ["futures", "tokio"]
categories = ["concurrency", "asynchronous"]
[dependencies]
tokio-executor = { version = "=0.2.0-alpha.1", path = "../tokio-executor" }
crossbeam-channel = "0.3.8"
[dev-dependencies]
tokio-sync = { version = "=0.2.0-alpha.1", path = "../tokio-sync" }

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-current-thread
Single threaded executor for Tokio.
## License
This project is licensed under the [MIT license](LICENSE).
### Contribution
Unless you explicitly state otherwise, any contribution intentionally submitted
for inclusion in Tokio by you, shall be licensed as MIT, without any additional
terms or conditions.

View File

@ -20,7 +20,11 @@ Future execution primitives
keywords = ["futures", "tokio"]
categories = ["concurrency", "asynchronous"]
[features]
current-thread = ["crossbeam-channel"]
[dependencies]
crossbeam-channel = { version = "0.3.8", optional = true }
[dev-dependencies]
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }

View File

@ -1,12 +1,3 @@
#![doc(html_root_url = "https://docs.rs/tokio-current-thread/0.2.0-alpha.1")]
#![warn(
missing_debug_implementations,
missing_docs,
rust_2018_idioms,
unreachable_pub
)]
#![doc(test(no_crate_inject, attr(deny(rust_2018_idioms))))]
//! A single-threaded executor which executes tasks on the same thread from which
//! they are spawned.
//!
@ -26,7 +17,10 @@
mod scheduler;
use crate::scheduler::Scheduler;
use self::scheduler::Scheduler;
use crate::park::{Park, ParkThread, Unpark};
use crate::{EnterError, Executor, SpawnError, TypedExecutor};
use std::cell::Cell;
use std::error::Error;
use std::fmt;
@ -37,8 +31,6 @@ use std::sync::{atomic, Arc};
use std::task::{Context, Poll, Waker};
use std::thread;
use std::time::{Duration, Instant};
use tokio_executor::park::{Park, ParkThread, Unpark};
use tokio_executor::SpawnError;
/// Executes tasks on the current thread
pub struct CurrentThread<P: Park = ParkThread> {
@ -318,21 +310,21 @@ impl<P: Park> CurrentThread<P> {
where
F: Future,
{
let _enter = tokio_executor::enter().expect("failed to start `current_thread::Runtime`");
let _enter = crate::enter().expect("failed to start `current_thread::Runtime`");
self.enter().block_on(future)
}
/// Run the executor to completion, blocking the thread until **all**
/// spawned futures have completed.
pub fn run(&mut self) -> Result<(), RunError> {
let _enter = tokio_executor::enter().expect("failed to start `current_thread::Runtime`");
let _enter = crate::enter().expect("failed to start `current_thread::Runtime`");
self.enter().run()
}
/// Run the executor to completion, blocking the thread until all
/// spawned futures have completed **or** `duration` time has elapsed.
pub fn run_timeout(&mut self, duration: Duration) -> Result<(), RunTimeoutError> {
let _enter = tokio_executor::enter().expect("failed to start `current_thread::Runtime`");
let _enter = crate::enter().expect("failed to start `current_thread::Runtime`");
self.enter().run_timeout(duration)
}
@ -340,7 +332,7 @@ impl<P: Park> CurrentThread<P> {
///
/// This function blocks the current thread even if the executor is idle.
pub fn turn(&mut self, duration: Option<Duration>) -> Result<Turn, TurnError> {
let _enter = tokio_executor::enter().expect("failed to start `current_thread::Runtime`");
let _enter = crate::enter().expect("failed to start `current_thread::Runtime`");
self.enter().turn(duration)
}
@ -394,7 +386,7 @@ impl<P: Park> Drop for CurrentThread<P> {
}
}
impl tokio_executor::Executor for CurrentThread {
impl Executor for CurrentThread {
fn spawn(
&mut self,
future: Pin<Box<dyn Future<Output = ()> + Send>>,
@ -404,7 +396,7 @@ impl tokio_executor::Executor for CurrentThread {
}
}
impl<T> tokio_executor::TypedExecutor<T> for CurrentThread
impl<T> TypedExecutor<T> for CurrentThread
where
T: Future<Output = ()> + 'static,
{
@ -723,7 +715,7 @@ impl TaskExecutor {
}
}
impl tokio_executor::Executor for TaskExecutor {
impl Executor for TaskExecutor {
fn spawn(
&mut self,
future: Pin<Box<dyn Future<Output = ()> + Send>>,
@ -732,7 +724,7 @@ impl tokio_executor::Executor for TaskExecutor {
}
}
impl<F> tokio_executor::TypedExecutor<F> for TaskExecutor
impl<F> TypedExecutor<F> for TaskExecutor
where
F: Future<Output = ()> + 'static,
{
@ -811,8 +803,8 @@ impl RunTimeoutError {
}
}
impl From<tokio_executor::EnterError> for RunTimeoutError {
fn from(_: tokio_executor::EnterError) -> Self {
impl From<EnterError> for RunTimeoutError {
fn from(_: EnterError) -> Self {
RunTimeoutError::new(false)
}
}
@ -826,8 +818,8 @@ impl<T> BlockError<T> {
}
}
impl<T> From<tokio_executor::EnterError> for BlockError<T> {
fn from(_: tokio_executor::EnterError) -> Self {
impl<T> From<EnterError> for BlockError<T> {
fn from(_: EnterError) -> Self {
BlockError { inner: None }
}
}

View File

@ -1,4 +1,6 @@
use crate::Borrow;
use super::Borrow;
use crate::park::Unpark;
use std::cell::UnsafeCell;
use std::fmt::{self, Debug};
use std::future::Future;
@ -11,7 +13,6 @@ use std::sync::{Arc, Weak};
use std::task::{Context, Poll, RawWaker, RawWakerVTable, Waker};
use std::thread;
use std::usize;
use tokio_executor::park::Unpark;
/// A generic task-aware scheduler.
///

View File

@ -64,6 +64,9 @@ mod global;
pub mod park;
mod typed;
#[cfg(feature = "current-thread")]
pub mod current_thread;
pub use crate::enter::{enter, exit, Enter, EnterError};
pub use crate::error::SpawnError;
pub use crate::executor::Executor;

View File

@ -1,6 +1,10 @@
#![warn(rust_2018_idioms)]
#![feature(async_await)]
use tokio::sync::oneshot;
use tokio_executor::current_thread::{self, block_on_all, CurrentThread, TaskExecutor};
use tokio_executor::TypedExecutor;
use std::any::Any;
use std::cell::{Cell, RefCell};
use std::future::Future;
@ -9,9 +13,6 @@ use std::rc::Rc;
use std::task::{Context, Poll};
use std::thread;
use std::time::Duration;
use tokio_current_thread::{block_on_all, CurrentThread};
use tokio_executor::TypedExecutor;
use tokio_sync::oneshot;
mod from_block_on_all {
use super::*;
@ -19,7 +20,7 @@ mod from_block_on_all {
let cnt = Rc::new(Cell::new(0));
let c = cnt.clone();
let msg = tokio_current_thread::block_on_all(async move {
let msg = block_on_all(async move {
c.set(1 + c.get());
// Spawn!
@ -36,15 +37,13 @@ mod from_block_on_all {
#[test]
fn spawn() {
test(tokio_current_thread::spawn)
test(current_thread::spawn)
}
#[test]
fn execute() {
test(|f| {
tokio_current_thread::TaskExecutor::current()
.spawn(f)
.unwrap();
TaskExecutor::current().spawn(f).unwrap();
});
}
}
@ -129,15 +128,13 @@ mod from_block_on_future {
#[test]
fn spawn() {
test(tokio_current_thread::spawn);
test(current_thread::spawn);
}
#[test]
fn execute() {
test(|f| {
tokio_current_thread::TaskExecutor::current()
.spawn(f)
.unwrap();
current_thread::TaskExecutor::current().spawn(f).unwrap();
});
}
}
@ -185,7 +182,7 @@ mod outstanding_tasks_are_dropped_when_executor_is_dropped {
#[test]
fn spawn() {
test(tokio_current_thread::spawn, |rt, f| {
test(current_thread::spawn, |rt, f| {
rt.spawn(f);
})
}
@ -194,9 +191,7 @@ mod outstanding_tasks_are_dropped_when_executor_is_dropped {
fn execute() {
test(
|f| {
tokio_current_thread::TaskExecutor::current()
.spawn(f)
.unwrap();
current_thread::TaskExecutor::current().spawn(f).unwrap();
},
// Note: `CurrentThread` doesn't currently implement
// `futures::Executor`, so we'll call `.spawn(...)` rather than
@ -224,7 +219,7 @@ mod run_in_future {
#[should_panic]
fn spawn() {
block_on_all(async {
tokio_current_thread::spawn(async {
current_thread::spawn(async {
block_on_all(async {});
});
});
@ -234,7 +229,7 @@ mod run_in_future {
#[should_panic]
fn execute() {
block_on_all(async {
tokio_current_thread::TaskExecutor::current()
current_thread::TaskExecutor::current()
.spawn(async {
block_on_all(async {});
})
@ -303,15 +298,13 @@ mod tasks_are_scheduled_fairly {
#[test]
fn spawn() {
test(tokio_current_thread::spawn)
test(current_thread::spawn)
}
#[test]
fn execute() {
test(|f| {
tokio_current_thread::TaskExecutor::current()
.spawn(f)
.unwrap();
current_thread::TaskExecutor::current().spawn(f).unwrap();
})
}
}
@ -358,7 +351,7 @@ mod and_turn {
#[test]
fn spawn() {
test(tokio_current_thread::spawn, |rt, f| {
test(current_thread::spawn, |rt, f| {
rt.spawn(f);
})
}
@ -367,9 +360,7 @@ mod and_turn {
fn execute() {
test(
|f| {
tokio_current_thread::TaskExecutor::current()
.spawn(f)
.unwrap();
current_thread::TaskExecutor::current().spawn(f).unwrap();
},
// Note: `CurrentThread` doesn't currently implement
// `futures::Executor`, so we'll call `.spawn(...)` rather than
@ -418,7 +409,7 @@ mod in_drop {
#[test]
fn spawn() {
test(tokio_current_thread::spawn, |rt, f| {
test(current_thread::spawn, |rt, f| {
rt.spawn(f);
})
}
@ -427,9 +418,7 @@ mod in_drop {
fn execute() {
test(
|f| {
tokio_current_thread::TaskExecutor::current()
.spawn(f)
.unwrap();
current_thread::TaskExecutor::current().spawn(f).unwrap();
},
// Note: `CurrentThread` doesn't currently implement
// `futures::Executor`, so we'll call `.spawn(...)` rather than

View File

@ -37,7 +37,6 @@ slab = "0.4.1"
[dev-dependencies]
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }
tokio-current-thread = { version = "=0.2.0-alpha.1", path = "../tokio-current-thread" }
tokio-sync = { version = "=0.2.0-alpha.1", path = "../tokio-sync", features = ["async-traits"] }
tokio-test = { version = "=0.2.0-alpha.1", path = "../tokio-test" }

View File

@ -1,7 +1,7 @@
#![warn(rust_2018_idioms)]
#![feature(async_await)]
use tokio_current_thread::CurrentThread;
use tokio_executor::current_thread::CurrentThread;
use tokio_executor::park::{Park, Unpark, UnparkThread};
use tokio_timer::{Delay, Timer};

View File

@ -45,8 +45,7 @@ rt-full = [
"reactor",
"sync",
"timer",
"tokio-current-thread",
"tokio-executor",
"tokio-executor/current-thread",
"tokio-macros",
"tokio-threadpool",
"tracing-core",
@ -66,7 +65,6 @@ futures-util-preview = { version = "=0.3.0-alpha.18", features = ["sink"] }
bytes = { version = "0.4", optional = true }
num_cpus = { version = "1.8.0", optional = true }
tokio-codec = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-codec" }
tokio-current-thread = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-current-thread" }
tokio-fs = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-fs" }
tokio-io = { version = "=0.2.0-alpha.1", optional = true, features = ["util"], path = "../tokio-io" }
tokio-executor = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-executor" }

View File

@ -1,8 +1,10 @@
use crate::runtime::current_thread::Runtime;
use tokio_current_thread::CurrentThread;
use tokio_executor::current_thread::CurrentThread;
use tokio_reactor::Reactor;
use tokio_timer::clock::Clock;
use tokio_timer::timer::Timer;
use std::io;
/// Builds a Single-threaded runtime with custom configuration values.

View File

@ -67,5 +67,5 @@ mod runtime;
pub use self::builder::Builder;
pub use self::runtime::{Handle, Runtime};
pub use tokio_current_thread::spawn;
pub use tokio_current_thread::TaskExecutor;
pub use tokio_executor::current_thread::spawn;
pub use tokio_executor::current_thread::TaskExecutor;

View File

@ -1,10 +1,11 @@
use crate::runtime::current_thread::Builder;
use tokio_current_thread::Handle as ExecutorHandle;
use tokio_current_thread::{self as current_thread, CurrentThread};
use tokio_executor;
use tokio_executor::current_thread::Handle as ExecutorHandle;
use tokio_executor::current_thread::{self, CurrentThread};
use tokio_reactor::{self, Reactor};
use tokio_timer::clock::{self, Clock};
use tokio_timer::timer::{self, Timer};
use std::error::Error;
use std::fmt;
use std::future::Future;

View File

@ -1,7 +1,7 @@
//! Temporary reactor + timer that runs on a background thread. This it to make
//! `block_on` work.
use tokio_current_thread::CurrentThread;
use tokio_executor::current_thread::CurrentThread;
use tokio_reactor::Reactor;
use tokio_sync::oneshot;
use tokio_timer::clock::Clock;

17
ui-tests/Cargo.toml Normal file
View File

@ -0,0 +1,17 @@
[package]
name = "ui-tests"
version = "0.1.0"
authors = ["Carl Lerche <me@carllerche.com>"]
edition = "2018"
publish = false
[features]
executor-without-current-thread = ["tokio-executor"]
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
[dependencies]
tokio-executor = { path = "../tokio-executor", optional = true }
[dev-dependencies]
trybuild = "1.0"

2
ui-tests/README.md Normal file
View File

@ -0,0 +1,2 @@
Tests the various combination of feature flags. This is broken out to a separate
crate to work around limitations with cargo features.

2
ui-tests/src/lib.rs Normal file
View File

@ -0,0 +1,2 @@
#[cfg(feature = "tokio-executor")]
pub use tokio_executor;

View File

@ -0,0 +1,9 @@
#[test]
fn features() {
let t = trybuild::TestCases::new();
#[cfg(feature = "executor-without-current-thread")]
t.compile_fail("tests/ui/executor_without_current_thread.rs");
drop(t);
}

View File

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

View File

@ -0,0 +1,7 @@
error[E0432]: unresolved import `ui_tests::tokio_executor::current_thread`
--> $DIR/executor_without_current_thread.rs:1:5
|
1 | use ui_tests::tokio_executor::current_thread;
| ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ no `current_thread` in `tokio_executor`
For more information about this error, try `rustc --explain E0432`.