mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-08 00:00:13 +02:00
threadpool: move threadpool into tokio-executor (#1452)
The threadpool is behind a feature flag. Refs: #1264
This commit is contained in:
@@ -13,7 +13,6 @@ members = [
|
|||||||
"tokio-signal",
|
"tokio-signal",
|
||||||
"tokio-sync",
|
"tokio-sync",
|
||||||
"tokio-test",
|
"tokio-test",
|
||||||
"tokio-threadpool",
|
|
||||||
"tokio-timer",
|
"tokio-timer",
|
||||||
"tokio-tcp",
|
"tokio-tcp",
|
||||||
"tokio-tls",
|
"tokio-tls",
|
||||||
|
|||||||
@@ -129,7 +129,8 @@ have greater guarantees of stability.
|
|||||||
|
|
||||||
The crates included as part of Tokio are:
|
The crates included as part of Tokio are:
|
||||||
|
|
||||||
* [`tokio-executor`]: Task executors and related utilities.
|
* [`tokio-executor`]: Task executors and related utilities. Includes a
|
||||||
|
single-threaded executor and a multi-threaded, work-stealing, executor.
|
||||||
|
|
||||||
* [`tokio-fs`]: Filesystem (and standard in / out) APIs.
|
* [`tokio-fs`]: Filesystem (and standard in / out) APIs.
|
||||||
|
|
||||||
@@ -144,9 +145,6 @@ The crates included as part of Tokio are:
|
|||||||
|
|
||||||
* [`tokio-tcp`]: TCP listener and acceptor.
|
* [`tokio-tcp`]: TCP listener and acceptor.
|
||||||
|
|
||||||
* [`tokio-threadpool`]: Schedules the execution of futures across a pool of
|
|
||||||
threads.
|
|
||||||
|
|
||||||
* [ `tokio-timer`]: Time related APIs.
|
* [ `tokio-timer`]: Time related APIs.
|
||||||
|
|
||||||
* [`tokio-udp`]: UDP socket.
|
* [`tokio-udp`]: UDP socket.
|
||||||
@@ -161,7 +159,6 @@ The crates included as part of Tokio are:
|
|||||||
[`tokio-macros`]: tokio-macros
|
[`tokio-macros`]: tokio-macros
|
||||||
[`tokio-net`]: tokio-net
|
[`tokio-net`]: tokio-net
|
||||||
[`tokio-tcp`]: tokio-tcp
|
[`tokio-tcp`]: tokio-tcp
|
||||||
[`tokio-threadpool`]: tokio-threadpool
|
|
||||||
[`tokio-timer`]: tokio-timer
|
[`tokio-timer`]: tokio-timer
|
||||||
[`tokio-udp`]: tokio-udp
|
[`tokio-udp`]: tokio-udp
|
||||||
[`tokio-uds`]: tokio-uds
|
[`tokio-uds`]: tokio-uds
|
||||||
|
|||||||
+1
-28
@@ -67,12 +67,12 @@ jobs:
|
|||||||
tokio-codec: []
|
tokio-codec: []
|
||||||
tokio-executor:
|
tokio-executor:
|
||||||
- current-thread
|
- current-thread
|
||||||
|
- threadpool
|
||||||
tokio-io:
|
tokio-io:
|
||||||
- util
|
- util
|
||||||
tokio-sync:
|
tokio-sync:
|
||||||
- async-traits
|
- async-traits
|
||||||
tokio-macros: []
|
tokio-macros: []
|
||||||
# - tokio-threadpool
|
|
||||||
tokio-timer:
|
tokio-timer:
|
||||||
- async-traits
|
- async-traits
|
||||||
tokio-test: []
|
tokio-test: []
|
||||||
@@ -89,33 +89,6 @@ jobs:
|
|||||||
- tokio-no-features
|
- tokio-no-features
|
||||||
- tokio-with-net
|
- tokio-with-net
|
||||||
|
|
||||||
# - template: ci/azure-cargo-check.yml
|
|
||||||
# parameters:
|
|
||||||
# name: features
|
|
||||||
# displayName: Check feature permtuations
|
|
||||||
# rust: stable
|
|
||||||
# crates:
|
|
||||||
# tokio:
|
|
||||||
# - codec
|
|
||||||
# - fs
|
|
||||||
# - io
|
|
||||||
# - reactor
|
|
||||||
# - rt-full
|
|
||||||
# - tcp
|
|
||||||
# - timer
|
|
||||||
# - udp
|
|
||||||
# - uds
|
|
||||||
# - sync
|
|
||||||
# tokio-buf:
|
|
||||||
# - util
|
|
||||||
#
|
|
||||||
# # Run async-await tests
|
|
||||||
# - template: ci/azure-test-nightly.yml
|
|
||||||
# parameters:
|
|
||||||
# name: test_nightly
|
|
||||||
# displayName: Test Async / Await
|
|
||||||
# rust: $(nightly)
|
|
||||||
#
|
|
||||||
# # Try cross compiling
|
# # Try cross compiling
|
||||||
# - template: ci/azure-cross-compile.yml
|
# - template: ci/azure-cross-compile.yml
|
||||||
# parameters:
|
# parameters:
|
||||||
|
|||||||
+1
-1
@@ -6,7 +6,7 @@ jobs:
|
|||||||
Timer:
|
Timer:
|
||||||
cmd: cargo test -p tokio-timer --test hammer
|
cmd: cargo test -p tokio-timer --test hammer
|
||||||
Threadpool:
|
Threadpool:
|
||||||
cmd: cargo test -p tokio-threadpool --tests
|
cmd: cargo test -p tokio-executor --tests --features threadpool
|
||||||
pool:
|
pool:
|
||||||
vmImage: ubuntu-16.04
|
vmImage: ubuntu-16.04
|
||||||
steps:
|
steps:
|
||||||
|
|||||||
@@ -11,7 +11,6 @@ tokio-macros = { path = "tokio-macros" }
|
|||||||
tokio-net = { path = "tokio-net" }
|
tokio-net = { path = "tokio-net" }
|
||||||
tokio-signal = { path = "tokio-signal" }
|
tokio-signal = { path = "tokio-signal" }
|
||||||
tokio-sync = { path = "tokio-sync" }
|
tokio-sync = { path = "tokio-sync" }
|
||||||
tokio-threadpool = { path = "tokio-threadpool" }
|
|
||||||
tokio-timer = { path = "tokio-timer" }
|
tokio-timer = { path = "tokio-timer" }
|
||||||
tokio-tcp = { path = "tokio-tcp" }
|
tokio-tcp = { path = "tokio-tcp" }
|
||||||
tokio-tls = { path = "tokio-tls" }
|
tokio-tls = { path = "tokio-tls" }
|
||||||
|
|||||||
@@ -22,11 +22,39 @@ categories = ["concurrency", "asynchronous"]
|
|||||||
|
|
||||||
[features]
|
[features]
|
||||||
current-thread = ["crossbeam-channel"]
|
current-thread = ["crossbeam-channel"]
|
||||||
|
threadpool = [
|
||||||
|
"tokio-sync",
|
||||||
|
"crossbeam-deque",
|
||||||
|
"crossbeam-queue",
|
||||||
|
"crossbeam-utils",
|
||||||
|
"futures-core-preview",
|
||||||
|
"futures-util-preview",
|
||||||
|
"num_cpus",
|
||||||
|
"log",
|
||||||
|
"lazy_static",
|
||||||
|
"slab",
|
||||||
|
]
|
||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
|
tokio-sync = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-sync" }
|
||||||
|
|
||||||
|
# current-thread dependencies
|
||||||
crossbeam-channel = { version = "0.3.8", optional = true }
|
crossbeam-channel = { version = "0.3.8", optional = true }
|
||||||
|
|
||||||
|
# threadpool dependencies
|
||||||
|
crossbeam-deque = { version = "0.7.0", optional = true }
|
||||||
|
crossbeam-queue = { version = "0.1.0", optional = true }
|
||||||
|
crossbeam-utils = { version = "0.6.4", optional = true }
|
||||||
|
futures-core-preview = { version = "=0.3.0-alpha.18", optional = true }
|
||||||
|
futures-util-preview = { version = "=0.3.0-alpha.18", optional = true }
|
||||||
|
num_cpus = { version = "1.2", optional = true }
|
||||||
|
log = { version = "0.4", optional = true }
|
||||||
|
lazy_static = { version = "1", optional = true }
|
||||||
|
slab = { version = "0.4.1", optional = true }
|
||||||
|
|
||||||
[dev-dependencies]
|
[dev-dependencies]
|
||||||
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }
|
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }
|
||||||
|
tokio-test = { version = "=0.2.0-alpha.1", path = "../tokio-test" }
|
||||||
|
|
||||||
futures-core-preview = "=0.3.0-alpha.18"
|
futures-core-preview = "=0.3.0-alpha.18"
|
||||||
|
rand = "0.7"
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ const ITER: usize = 1_000;
|
|||||||
mod blocking {
|
mod blocking {
|
||||||
use super::*;
|
use super::*;
|
||||||
use futures::future::*;
|
use futures::future::*;
|
||||||
use tokio_threadpool::{blocking, Builder};
|
use tokio_executor::threadpool::{blocking, Builder};
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn cpu_bound(b: &mut test::Bencher) {
|
fn cpu_bound(b: &mut test::Bencher) {
|
||||||
@@ -39,7 +39,7 @@ mod message_passing {
|
|||||||
use super::*;
|
use super::*;
|
||||||
use futures::future::*;
|
use futures::future::*;
|
||||||
use futures::sync::oneshot;
|
use futures::sync::oneshot;
|
||||||
use tokio_threadpool::Builder;
|
use tokio_executor::threadpool::Builder;
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn cpu_bound(b: &mut test::Bencher) {
|
fn cpu_bound(b: &mut test::Bencher) {
|
||||||
@@ -13,7 +13,7 @@ mod threadpool {
|
|||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering::SeqCst;
|
use std::sync::atomic::Ordering::SeqCst;
|
||||||
use std::sync::{mpsc, Arc};
|
use std::sync::{mpsc, Arc};
|
||||||
use tokio_threadpool::*;
|
use tokio_executor::threadpool::*;
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn spawn_many(b: &mut test::Bencher) {
|
fn spawn_many(b: &mut test::Bencher) {
|
||||||
@@ -8,7 +8,7 @@ const ITER: usize = 20_000;
|
|||||||
mod us {
|
mod us {
|
||||||
use futures::future;
|
use futures::future;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
use tokio_threadpool::*;
|
use tokio_executor::threadpool::*;
|
||||||
|
|
||||||
#[bench]
|
#[bench]
|
||||||
fn chained_spawn(b: &mut test::Bencher) {
|
fn chained_spawn(b: &mut test::Bencher) {
|
||||||
@@ -67,6 +67,9 @@ mod typed;
|
|||||||
#[cfg(feature = "current-thread")]
|
#[cfg(feature = "current-thread")]
|
||||||
pub mod current_thread;
|
pub mod current_thread;
|
||||||
|
|
||||||
|
#[cfg(feature = "threadpool")]
|
||||||
|
pub mod threadpool;
|
||||||
|
|
||||||
pub use crate::enter::{enter, exit, Enter, EnterError};
|
pub use crate::enter::{enter, exit, Enter, EnterError};
|
||||||
pub use crate::error::SpawnError;
|
pub use crate::error::SpawnError;
|
||||||
pub use crate::executor::Executor;
|
pub use crate::executor::Executor;
|
||||||
|
|||||||
@@ -1,10 +1,9 @@
|
|||||||
use crate::worker::Worker;
|
use super::worker::Worker;
|
||||||
|
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::task::Poll;
|
use std::task::Poll;
|
||||||
use tokio_executor;
|
|
||||||
|
|
||||||
/// Error raised by `blocking`.
|
/// Error raised by `blocking`.
|
||||||
pub struct BlockingError {
|
pub struct BlockingError {
|
||||||
@@ -83,7 +82,7 @@ pub struct BlockingError {
|
|||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(async_await)]
|
/// #![feature(async_await)]
|
||||||
///
|
///
|
||||||
/// use tokio_threadpool::{ThreadPool, blocking};
|
/// use tokio_executor::threadpool::{ThreadPool, blocking};
|
||||||
///
|
///
|
||||||
/// use futures_util::future::poll_fn;
|
/// use futures_util::future::poll_fn;
|
||||||
/// use std::sync::mpsc;
|
/// use std::sync::mpsc;
|
||||||
@@ -144,7 +143,7 @@ where
|
|||||||
//
|
//
|
||||||
// "Exit" the current executor in case the blocking function wants
|
// "Exit" the current executor in case the blocking function wants
|
||||||
// to call a different executor.
|
// to call a different executor.
|
||||||
let ret = tokio_executor::exit(move || f());
|
let ret = crate::exit(move || f());
|
||||||
|
|
||||||
// Try to transition out of blocking mode. This is a fast path that takes
|
// Try to transition out of blocking mode. This is a fast path that takes
|
||||||
// back ownership of the worker if the worker handoff didn't complete yet.
|
// back ownership of the worker if the worker handoff didn't complete yet.
|
||||||
@@ -1,10 +1,12 @@
|
|||||||
use crate::callback::Callback;
|
use super::callback::Callback;
|
||||||
use crate::config::{Config, MAX_WORKERS};
|
use super::config::{Config, MAX_WORKERS};
|
||||||
use crate::park::{BoxPark, BoxedPark, DefaultPark};
|
use super::park::{BoxPark, BoxedPark, DefaultPark};
|
||||||
use crate::pool::{Pool, MAX_BACKUP};
|
use super::pool::{Pool, MAX_BACKUP};
|
||||||
use crate::shutdown::ShutdownTrigger;
|
use super::shutdown::ShutdownTrigger;
|
||||||
use crate::thread_pool::ThreadPool;
|
use super::thread_pool::ThreadPool;
|
||||||
use crate::worker::{self, Worker, WorkerId};
|
use super::worker::{self, Worker, WorkerId};
|
||||||
|
use crate::park::Park;
|
||||||
|
|
||||||
use crossbeam_deque::Injector;
|
use crossbeam_deque::Injector;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use num_cpus;
|
use num_cpus;
|
||||||
@@ -14,7 +16,6 @@ use std::error::Error;
|
|||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio_executor::park::Park;
|
|
||||||
|
|
||||||
/// Builds a thread pool with custom configuration values.
|
/// Builds a thread pool with custom configuration values.
|
||||||
///
|
///
|
||||||
@@ -34,7 +35,7 @@ use tokio_executor::park::Park;
|
|||||||
/// ```
|
/// ```
|
||||||
/// #![feature(async_await)]
|
/// #![feature(async_await)]
|
||||||
///
|
///
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// use std::time::Duration;
|
/// use std::time::Duration;
|
||||||
///
|
///
|
||||||
@@ -74,7 +75,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
/// use std::time::Duration;
|
/// use std::time::Duration;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
@@ -114,7 +115,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .pool_size(4)
|
/// .pool_size(4)
|
||||||
@@ -142,7 +143,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .max_blocking(200)
|
/// .max_blocking(200)
|
||||||
@@ -168,7 +169,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
/// use std::time::Duration;
|
/// use std::time::Duration;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
@@ -190,7 +191,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .panic_handler(|err| std::panic::resume_unwind(err))
|
/// .panic_handler(|err| std::panic::resume_unwind(err))
|
||||||
@@ -216,7 +217,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .name_prefix("my-pool-")
|
/// .name_prefix("my-pool-")
|
||||||
@@ -238,7 +239,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .stack_size(32 * 1024)
|
/// .stack_size(32 * 1024)
|
||||||
@@ -258,7 +259,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .around_worker(|worker| {
|
/// .around_worker(|worker| {
|
||||||
@@ -286,7 +287,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .after_start(|| {
|
/// .after_start(|| {
|
||||||
@@ -309,7 +310,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .before_stop(|| {
|
/// .before_stop(|| {
|
||||||
@@ -333,13 +334,12 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
|
/// use tokio_executor::threadpool::park::DefaultPark;
|
||||||
/// # fn decorate<F>(f: F) -> F { f }
|
/// # fn decorate<F>(f: F) -> F { f }
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .custom_park(|_| {
|
/// .custom_park(|_| {
|
||||||
/// use tokio_threadpool::park::DefaultPark;
|
|
||||||
///
|
|
||||||
/// // This is the default park type that the worker would use if we
|
/// // This is the default park type that the worker would use if we
|
||||||
/// // did not customize it.
|
/// // did not customize it.
|
||||||
/// let park = DefaultPark::new();
|
/// let park = DefaultPark::new();
|
||||||
@@ -368,7 +368,7 @@ impl Builder {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```
|
/// ```
|
||||||
/// use tokio_threadpool::Builder;
|
/// use tokio_executor::threadpool::Builder;
|
||||||
///
|
///
|
||||||
/// let thread_pool = Builder::new()
|
/// let thread_pool = Builder::new()
|
||||||
/// .build();
|
/// .build();
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::worker::Worker;
|
use super::worker::Worker;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
|
|
||||||
@@ -1,4 +1,5 @@
|
|||||||
use crate::callback::Callback;
|
use super::callback::Callback;
|
||||||
|
|
||||||
use std::any::Any;
|
use std::any::Any;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -1,12 +1,3 @@
|
|||||||
#![doc(html_root_url = "https://docs.rs/tokio-threadpool/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 work-stealing based thread pool for executing futures.
|
//! A work-stealing based thread pool for executing futures.
|
||||||
//!
|
//!
|
||||||
//! The Tokio thread pool supports scheduling futures and processing them on
|
//! The Tokio thread pool supports scheduling futures and processing them on
|
||||||
@@ -147,9 +138,9 @@ mod thread_pool;
|
|||||||
mod waker;
|
mod waker;
|
||||||
mod worker;
|
mod worker;
|
||||||
|
|
||||||
pub use crate::blocking::{blocking, BlockingError};
|
pub use self::blocking::{blocking, BlockingError};
|
||||||
pub use crate::builder::Builder;
|
pub use self::builder::Builder;
|
||||||
pub use crate::sender::Sender;
|
pub use self::sender::Sender;
|
||||||
pub use crate::shutdown::Shutdown;
|
pub use self::shutdown::Shutdown;
|
||||||
pub use crate::thread_pool::ThreadPool;
|
pub use self::thread_pool::ThreadPool;
|
||||||
pub use crate::worker::{Worker, WorkerId};
|
pub use self::worker::{Worker, WorkerId};
|
||||||
@@ -1,7 +1,8 @@
|
|||||||
|
use crate::park::{Park, Unpark};
|
||||||
|
|
||||||
use log::warn;
|
use log::warn;
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio_executor::park::{Park, Unpark};
|
|
||||||
|
|
||||||
pub(crate) type BoxPark = Box<dyn Park<Unpark = BoxUnpark, Error = ()> + Send>;
|
pub(crate) type BoxPark = Box<dyn Park<Unpark = BoxUnpark, Error = ()> + Send>;
|
||||||
pub(crate) type BoxUnpark = Box<dyn Unpark>;
|
pub(crate) type BoxUnpark = Box<dyn Unpark>;
|
||||||
+2
-1
@@ -1,8 +1,9 @@
|
|||||||
|
use crate::park::{Park, Unpark};
|
||||||
|
|
||||||
use crossbeam_utils::sync::{Parker, Unparker};
|
use crossbeam_utils::sync::{Parker, Unparker};
|
||||||
use std::error::Error;
|
use std::error::Error;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::time::Duration;
|
use std::time::Duration;
|
||||||
use tokio_executor::park::{Park, Unpark};
|
|
||||||
|
|
||||||
/// Parks the thread.
|
/// Parks the thread.
|
||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::park::DefaultPark;
|
use super::super::park::DefaultPark;
|
||||||
use crate::worker::WorkerId;
|
use super::super::worker::WorkerId;
|
||||||
|
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
+1
-1
@@ -1,4 +1,4 @@
|
|||||||
use crate::pool::{Backup, BackupId};
|
use super::{Backup, BackupId};
|
||||||
|
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering::{AcqRel, Acquire};
|
use std::sync::atomic::Ordering::{AcqRel, Acquire};
|
||||||
@@ -8,14 +8,14 @@ pub(crate) use self::state::{Lifecycle, State, MAX_FUTURES};
|
|||||||
|
|
||||||
use self::backup::Handoff;
|
use self::backup::Handoff;
|
||||||
use self::backup_stack::BackupStack;
|
use self::backup_stack::BackupStack;
|
||||||
|
use super::config::Config;
|
||||||
|
use super::shutdown::ShutdownTrigger;
|
||||||
|
use super::task::{Blocking, Task};
|
||||||
|
use super::worker::{self, Worker, WorkerId};
|
||||||
|
use super::BlockingError;
|
||||||
|
|
||||||
use crate::config::Config;
|
|
||||||
use crate::shutdown::ShutdownTrigger;
|
|
||||||
use crate::task::{Blocking, Task};
|
|
||||||
use crate::worker::{self, Worker, WorkerId};
|
|
||||||
use crossbeam_deque::Injector;
|
use crossbeam_deque::Injector;
|
||||||
use crossbeam_utils::CachePadded;
|
use crossbeam_utils::CachePadded;
|
||||||
|
|
||||||
use lazy_static::lazy_static;
|
use lazy_static::lazy_static;
|
||||||
use log::{debug, error, trace};
|
use log::{debug, error, trace};
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
@@ -203,7 +203,7 @@ impl Pool {
|
|||||||
}
|
}
|
||||||
|
|
||||||
pub(crate) fn terminate_sleeping_workers(&self) {
|
pub(crate) fn terminate_sleeping_workers(&self) {
|
||||||
use crate::worker::Lifecycle::Signaled;
|
use super::worker::Lifecycle::Signaled;
|
||||||
|
|
||||||
trace!(" -> shutting down workers");
|
trace!(" -> shutting down workers");
|
||||||
// Wakeup all sleeping workers. They will wake up, see the state
|
// Wakeup all sleeping workers. They will wake up, see the state
|
||||||
@@ -225,7 +225,7 @@ impl Pool {
|
|||||||
pub(crate) fn poll_blocking_capacity(
|
pub(crate) fn poll_blocking_capacity(
|
||||||
&self,
|
&self,
|
||||||
task: &Arc<Task>,
|
task: &Arc<Task>,
|
||||||
) -> Poll<Result<(), crate::BlockingError>> {
|
) -> Poll<Result<(), BlockingError>> {
|
||||||
self.blocking.poll_blocking_capacity(task)
|
self.blocking.poll_blocking_capacity(task)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -399,7 +399,7 @@ impl Pool {
|
|||||||
pub(crate) fn signal_work(&self, pool: &Arc<Pool>) {
|
pub(crate) fn signal_work(&self, pool: &Arc<Pool>) {
|
||||||
debug_assert_eq!(*self, **pool);
|
debug_assert_eq!(*self, **pool);
|
||||||
|
|
||||||
use crate::worker::Lifecycle::Signaled;
|
use super::worker::Lifecycle::Signaled;
|
||||||
|
|
||||||
if let Some((idx, worker_state)) = self.sleep_stack.pop(&self.workers, Signaled, false) {
|
if let Some((idx, worker_state)) = self.sleep_stack.pop(&self.workers, Signaled, false) {
|
||||||
let entry = &self.workers[idx];
|
let entry = &self.workers[idx];
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::pool::{self, Lifecycle, Pool, MAX_FUTURES};
|
use super::pool::{self, Lifecycle, Pool, MAX_FUTURES};
|
||||||
use crate::task::Task;
|
use super::task::Task;
|
||||||
|
|
||||||
use tokio_executor::{self, SpawnError};
|
use crate::{Executor, SpawnError, TypedExecutor};
|
||||||
|
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
@@ -62,7 +62,7 @@ impl Sender {
|
|||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(async_await)]
|
/// #![feature(async_await)]
|
||||||
///
|
///
|
||||||
/// use tokio_threadpool::ThreadPool;
|
/// use tokio_executor::threadpool::ThreadPool;
|
||||||
///
|
///
|
||||||
/// // Create a thread pool with default configuration values
|
/// // Create a thread pool with default configuration values
|
||||||
/// let thread_pool = ThreadPool::new();
|
/// let thread_pool = ThreadPool::new();
|
||||||
@@ -79,7 +79,7 @@ impl Sender {
|
|||||||
F: Future<Output = ()> + Send + 'static,
|
F: Future<Output = ()> + Send + 'static,
|
||||||
{
|
{
|
||||||
let mut s = self;
|
let mut s = self;
|
||||||
tokio_executor::Executor::spawn(&mut s, Box::pin(future))
|
Executor::spawn(&mut s, Box::pin(future))
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Logic to prepare for spawning
|
/// Logic to prepare for spawning
|
||||||
@@ -121,10 +121,10 @@ impl Sender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl tokio_executor::Executor for Sender {
|
impl Executor for Sender {
|
||||||
fn status(&self) -> Result<(), tokio_executor::SpawnError> {
|
fn status(&self) -> Result<(), SpawnError> {
|
||||||
let s = self;
|
let s = self;
|
||||||
tokio_executor::Executor::status(&s)
|
Executor::status(&s)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn(
|
fn spawn(
|
||||||
@@ -132,12 +132,12 @@ impl tokio_executor::Executor for Sender {
|
|||||||
future: Pin<Box<dyn Future<Output = ()> + Send>>,
|
future: Pin<Box<dyn Future<Output = ()> + Send>>,
|
||||||
) -> Result<(), SpawnError> {
|
) -> Result<(), SpawnError> {
|
||||||
let mut s = &*self;
|
let mut s = &*self;
|
||||||
tokio_executor::Executor::spawn(&mut s, future)
|
Executor::spawn(&mut s, future)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl tokio_executor::Executor for &Sender {
|
impl Executor for &Sender {
|
||||||
fn status(&self) -> Result<(), tokio_executor::SpawnError> {
|
fn status(&self) -> Result<(), SpawnError> {
|
||||||
let state: pool::State = self.pool.state.load(Acquire).into();
|
let state: pool::State = self.pool.state.load(Acquire).into();
|
||||||
|
|
||||||
if state.num_futures() == MAX_FUTURES {
|
if state.num_futures() == MAX_FUTURES {
|
||||||
@@ -174,16 +174,16 @@ impl tokio_executor::Executor for &Sender {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
impl<T> tokio_executor::TypedExecutor<T> for Sender
|
impl<T> TypedExecutor<T> for Sender
|
||||||
where
|
where
|
||||||
T: Future<Output = ()> + Send + 'static,
|
T: Future<Output = ()> + Send + 'static,
|
||||||
{
|
{
|
||||||
fn status(&self) -> Result<(), tokio_executor::SpawnError> {
|
fn status(&self) -> Result<(), SpawnError> {
|
||||||
tokio_executor::Executor::status(self)
|
Executor::status(self)
|
||||||
}
|
}
|
||||||
|
|
||||||
fn spawn(&mut self, future: T) -> Result<(), SpawnError> {
|
fn spawn(&mut self, future: T) -> Result<(), SpawnError> {
|
||||||
tokio_executor::Executor::spawn(self, Box::pin(future))
|
Executor::spawn(self, Box::pin(future))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::task::Task;
|
use super::task::Task;
|
||||||
use crate::worker;
|
use super::worker;
|
||||||
|
|
||||||
use tokio_sync::AtomicWaker;
|
use tokio_sync::AtomicWaker;
|
||||||
|
|
||||||
@@ -45,7 +45,7 @@ impl Shutdown {
|
|||||||
|
|
||||||
/// Wait for the shutdown to complete
|
/// Wait for the shutdown to complete
|
||||||
pub fn wait(self) {
|
pub fn wait(self) {
|
||||||
let mut enter = tokio_executor::enter().unwrap();
|
let mut enter = crate::enter().unwrap();
|
||||||
enter.block_on(self);
|
enter.block_on(self);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
+4
-3
@@ -1,5 +1,6 @@
|
|||||||
use crate::pool::Pool;
|
use super::super::pool::Pool;
|
||||||
use crate::task::{BlockingState, Task};
|
use super::super::task::{BlockingState, Task};
|
||||||
|
use crate::threadpool::BlockingError;
|
||||||
|
|
||||||
use std::cell::UnsafeCell;
|
use std::cell::UnsafeCell;
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
@@ -113,7 +114,7 @@ impl Blocking {
|
|||||||
pub(crate) fn poll_blocking_capacity(
|
pub(crate) fn poll_blocking_capacity(
|
||||||
&self,
|
&self,
|
||||||
task: &Arc<Task>,
|
task: &Arc<Task>,
|
||||||
) -> Poll<Result<(), crate::BlockingError>> {
|
) -> Poll<Result<(), BlockingError>> {
|
||||||
// This requires atomically claiming blocking capacity and if none is
|
// This requires atomically claiming blocking capacity and if none is
|
||||||
// available, queuing &task.
|
// available, queuing &task.
|
||||||
|
|
||||||
+2
-1
@@ -1,4 +1,5 @@
|
|||||||
use crate::task::CanBlock;
|
use super::CanBlock;
|
||||||
|
|
||||||
use std::fmt;
|
use std::fmt;
|
||||||
use std::sync::atomic::{AtomicUsize, Ordering};
|
use std::sync::atomic::{AtomicUsize, Ordering};
|
||||||
|
|
||||||
@@ -5,8 +5,8 @@ mod state;
|
|||||||
pub(crate) use self::blocking::{Blocking, CanBlock};
|
pub(crate) use self::blocking::{Blocking, CanBlock};
|
||||||
use self::blocking_state::BlockingState;
|
use self::blocking_state::BlockingState;
|
||||||
use self::state::State;
|
use self::state::State;
|
||||||
use crate::pool::Pool;
|
use super::pool::Pool;
|
||||||
use crate::waker::Waker;
|
use super::waker::Waker;
|
||||||
|
|
||||||
use futures_util::task;
|
use futures_util::task;
|
||||||
use log::trace;
|
use log::trace;
|
||||||
@@ -1,7 +1,7 @@
|
|||||||
use crate::builder::Builder;
|
use super::builder::Builder;
|
||||||
use crate::pool::Pool;
|
use super::pool::Pool;
|
||||||
use crate::sender::Sender;
|
use super::sender::Sender;
|
||||||
use crate::shutdown::{Shutdown, ShutdownTrigger};
|
use super::shutdown::{Shutdown, ShutdownTrigger};
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
@@ -53,7 +53,7 @@ impl ThreadPool {
|
|||||||
/// ```rust
|
/// ```rust
|
||||||
/// #![feature(async_await)]
|
/// #![feature(async_await)]
|
||||||
///
|
///
|
||||||
/// use tokio_threadpool::ThreadPool;
|
/// use tokio_executor::threadpool::ThreadPool;
|
||||||
///
|
///
|
||||||
/// // Create a thread pool with default configuration values
|
/// // Create a thread pool with default configuration values
|
||||||
/// let thread_pool = ThreadPool::new();
|
/// let thread_pool = ThreadPool::new();
|
||||||
@@ -90,7 +90,7 @@ impl ThreadPool {
|
|||||||
/// # Examples
|
/// # Examples
|
||||||
///
|
///
|
||||||
/// ```rust
|
/// ```rust
|
||||||
/// # use tokio_threadpool::ThreadPool;
|
/// # use tokio_executor::threadpool::ThreadPool;
|
||||||
/// use futures::future::{Future, lazy};
|
/// use futures::future::{Future, lazy};
|
||||||
///
|
///
|
||||||
/// // Create a thread pool with default configuration values
|
/// // Create a thread pool with default configuration values
|
||||||
@@ -188,7 +188,7 @@ impl Drop for ThreadPool {
|
|||||||
drop(inner);
|
drop(inner);
|
||||||
|
|
||||||
// Wait until all worker threads terminate and the threadpool's resources clean up.
|
// Wait until all worker threads terminate and the threadpool's resources clean up.
|
||||||
let mut enter = match tokio_executor::enter() {
|
let mut enter = match crate::enter() {
|
||||||
Ok(e) => e,
|
Ok(e) => e,
|
||||||
Err(_) => return,
|
Err(_) => return,
|
||||||
};
|
};
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
use crate::pool::Pool;
|
use super::pool::Pool;
|
||||||
use crate::task::Task;
|
use super::task::Task;
|
||||||
|
|
||||||
use futures_util::task::ArcWake;
|
use futures_util::task::ArcWake;
|
||||||
use std::sync::Arc;
|
use std::sync::Arc;
|
||||||
+6
-5
@@ -1,6 +1,7 @@
|
|||||||
use crate::park::{BoxPark, BoxUnpark};
|
use super::super::park::{BoxPark, BoxUnpark};
|
||||||
use crate::task::Task;
|
use super::super::task::Task;
|
||||||
use crate::worker::state::{State, PUSHED_MASK};
|
use super::state::{State, PUSHED_MASK};
|
||||||
|
|
||||||
use crossbeam_deque::{Steal, Stealer, Worker};
|
use crossbeam_deque::{Steal, Stealer, Worker};
|
||||||
use crossbeam_queue::SegQueue;
|
use crossbeam_queue::SegQueue;
|
||||||
use crossbeam_utils::CachePadded;
|
use crossbeam_utils::CachePadded;
|
||||||
@@ -94,7 +95,7 @@ impl WorkerEntry {
|
|||||||
/// The `state` must have been obtained with an `Acquire` ordering.
|
/// The `state` must have been obtained with an `Acquire` ordering.
|
||||||
#[inline]
|
#[inline]
|
||||||
pub(crate) fn notify(&self, mut state: State) -> bool {
|
pub(crate) fn notify(&self, mut state: State) -> bool {
|
||||||
use crate::worker::Lifecycle::*;
|
use super::Lifecycle::*;
|
||||||
|
|
||||||
loop {
|
loop {
|
||||||
let mut next = state;
|
let mut next = state;
|
||||||
@@ -139,7 +140,7 @@ impl WorkerEntry {
|
|||||||
///
|
///
|
||||||
/// Returns `Err` if the worker has already terminated.
|
/// Returns `Err` if the worker has already terminated.
|
||||||
pub(crate) fn signal_stop(&self, mut state: State) {
|
pub(crate) fn signal_stop(&self, mut state: State) {
|
||||||
use crate::worker::Lifecycle::*;
|
use super::Lifecycle::*;
|
||||||
|
|
||||||
// Transition the worker state to signaled
|
// Transition the worker state to signaled
|
||||||
loop {
|
loop {
|
||||||
@@ -6,12 +6,11 @@ pub(crate) use self::entry::WorkerEntry as Entry;
|
|||||||
pub(crate) use self::stack::Stack;
|
pub(crate) use self::stack::Stack;
|
||||||
pub(crate) use self::state::{Lifecycle, State};
|
pub(crate) use self::state::{Lifecycle, State};
|
||||||
|
|
||||||
use crate::pool::{self, BackupId, Pool};
|
use super::pool::{self, BackupId, Pool};
|
||||||
use crate::sender::Sender;
|
use super::sender::Sender;
|
||||||
use crate::shutdown::ShutdownTrigger;
|
use super::shutdown::ShutdownTrigger;
|
||||||
use crate::task::{self, CanBlock, Task};
|
use super::task::{self, CanBlock, Task};
|
||||||
|
use super::BlockingError;
|
||||||
use tokio_executor;
|
|
||||||
|
|
||||||
use log::trace;
|
use log::trace;
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
@@ -120,9 +119,9 @@ impl Worker {
|
|||||||
let mut sender = Sender { pool };
|
let mut sender = Sender { pool };
|
||||||
|
|
||||||
// Enter an execution context
|
// Enter an execution context
|
||||||
let _enter = tokio_executor::enter().unwrap();
|
let _enter = crate::enter().unwrap();
|
||||||
|
|
||||||
tokio_executor::with_default(&mut sender, || {
|
crate::with_default(&mut sender, || {
|
||||||
if let Some(ref callback) = self.pool.config.around_worker {
|
if let Some(ref callback) = self.pool.config.around_worker {
|
||||||
callback.call(self);
|
callback.call(self);
|
||||||
} else {
|
} else {
|
||||||
@@ -150,7 +149,7 @@ impl Worker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/// Transition the current worker to a blocking worker
|
/// Transition the current worker to a blocking worker
|
||||||
pub(crate) fn transition_to_blocking(&self) -> Poll<Result<(), crate::BlockingError>> {
|
pub(crate) fn transition_to_blocking(&self) -> Poll<Result<(), BlockingError>> {
|
||||||
use self::CanBlock::*;
|
use self::CanBlock::*;
|
||||||
|
|
||||||
// If we get this far, then `current_task` has been set.
|
// If we get this far, then `current_task` has been set.
|
||||||
@@ -442,7 +441,7 @@ impl Worker {
|
|||||||
}
|
}
|
||||||
|
|
||||||
fn run_task(&self, task: Arc<Task>, pool: &Arc<Pool>) {
|
fn run_task(&self, task: Arc<Task>, pool: &Arc<Pool>) {
|
||||||
use crate::task::Run::*;
|
use super::task::Run::*;
|
||||||
|
|
||||||
// If this is the first time this task is being polled, register it so that we can keep
|
// If this is the first time this task is being polled, register it so that we can keep
|
||||||
// track of tasks that are in progress.
|
// track of tasks that are in progress.
|
||||||
+3
-2
@@ -1,5 +1,6 @@
|
|||||||
use crate::config::MAX_WORKERS;
|
use super::super::config::MAX_WORKERS;
|
||||||
use crate::worker;
|
use super::super::worker;
|
||||||
|
|
||||||
use std::sync::atomic::AtomicUsize;
|
use std::sync::atomic::AtomicUsize;
|
||||||
use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed};
|
use std::sync::atomic::Ordering::{AcqRel, Acquire, Relaxed};
|
||||||
use std::{fmt, usize};
|
use std::{fmt, usize};
|
||||||
@@ -2,9 +2,10 @@
|
|||||||
#![feature(async_await)]
|
#![feature(async_await)]
|
||||||
|
|
||||||
use tokio_executor::park::{Park, Unpark};
|
use tokio_executor::park::{Park, Unpark};
|
||||||
|
use tokio_executor::threadpool;
|
||||||
|
use tokio_executor::threadpool::park::{DefaultPark, DefaultUnpark};
|
||||||
|
use tokio_executor::threadpool::*;
|
||||||
use tokio_test::assert_pending;
|
use tokio_test::assert_pending;
|
||||||
use tokio_threadpool::park::{DefaultPark, DefaultUnpark};
|
|
||||||
use tokio_threadpool::*;
|
|
||||||
|
|
||||||
use std::cell::Cell;
|
use std::cell::Cell;
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
@@ -19,8 +20,6 @@ thread_local!(static FOO: Cell<u32> = Cell::new(0));
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn natural_shutdown_simple_futures() {
|
fn natural_shutdown_simple_futures() {
|
||||||
let _ = ::env_logger::try_init();
|
|
||||||
|
|
||||||
for _ in 0..1_000 {
|
for _ in 0..1_000 {
|
||||||
let num_inc = Arc::new(AtomicUsize::new(0));
|
let num_inc = Arc::new(AtomicUsize::new(0));
|
||||||
let num_dec = Arc::new(AtomicUsize::new(0));
|
let num_dec = Arc::new(AtomicUsize::new(0));
|
||||||
@@ -88,8 +87,6 @@ fn natural_shutdown_simple_futures() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn force_shutdown_drops_futures() {
|
fn force_shutdown_drops_futures() {
|
||||||
let _ = ::env_logger::try_init();
|
|
||||||
|
|
||||||
for _ in 0..1_000 {
|
for _ in 0..1_000 {
|
||||||
let num_inc = Arc::new(AtomicUsize::new(0));
|
let num_inc = Arc::new(AtomicUsize::new(0));
|
||||||
let num_dec = Arc::new(AtomicUsize::new(0));
|
let num_dec = Arc::new(AtomicUsize::new(0));
|
||||||
@@ -144,8 +141,6 @@ fn force_shutdown_drops_futures() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn drop_threadpool_drops_futures() {
|
fn drop_threadpool_drops_futures() {
|
||||||
let _ = ::env_logger::try_init();
|
|
||||||
|
|
||||||
for _ in 0..1_000 {
|
for _ in 0..1_000 {
|
||||||
let num_inc = Arc::new(AtomicUsize::new(0));
|
let num_inc = Arc::new(AtomicUsize::new(0));
|
||||||
let num_dec = Arc::new(AtomicUsize::new(0));
|
let num_dec = Arc::new(AtomicUsize::new(0));
|
||||||
@@ -204,8 +199,6 @@ fn drop_threadpool_drops_futures() {
|
|||||||
fn many_oneshot_futures() {
|
fn many_oneshot_futures() {
|
||||||
const NUM: usize = 10_000;
|
const NUM: usize = 10_000;
|
||||||
|
|
||||||
let _ = ::env_logger::try_init();
|
|
||||||
|
|
||||||
for _ in 0..50 {
|
for _ in 0..50 {
|
||||||
let pool = ThreadPool::new();
|
let pool = ThreadPool::new();
|
||||||
let tx = pool.sender().clone();
|
let tx = pool.sender().clone();
|
||||||
@@ -235,8 +228,6 @@ fn many_multishot_futures() {
|
|||||||
const CYCLES: usize = 5;
|
const CYCLES: usize = 5;
|
||||||
const TRACKS: usize = 50;
|
const TRACKS: usize = 50;
|
||||||
|
|
||||||
let _ = ::env_logger::try_init();
|
|
||||||
|
|
||||||
for _ in 0..50 {
|
for _ in 0..50 {
|
||||||
let pool = ThreadPool::new();
|
let pool = ThreadPool::new();
|
||||||
let pool_tx = pool.sender().clone();
|
let pool_tx = pool.sender().clone();
|
||||||
@@ -398,7 +389,7 @@ fn panic_in_task() {
|
|||||||
fn count_panics() {
|
fn count_panics() {
|
||||||
let counter = Arc::new(AtomicUsize::new(0));
|
let counter = Arc::new(AtomicUsize::new(0));
|
||||||
let counter_ = counter.clone();
|
let counter_ = counter.clone();
|
||||||
let pool = tokio_threadpool::Builder::new()
|
let pool = threadpool::Builder::new()
|
||||||
.panic_handler(move |_err| {
|
.panic_handler(move |_err| {
|
||||||
// We caught a panic.
|
// We caught a panic.
|
||||||
counter_.fetch_add(1, Relaxed);
|
counter_.fetch_add(1, Relaxed);
|
||||||
@@ -481,7 +472,7 @@ fn eagerly_drops_futures() {
|
|||||||
let (park_tx, park_rx) = mpsc::sync_channel(0);
|
let (park_tx, park_rx) = mpsc::sync_channel(0);
|
||||||
let (unpark_tx, unpark_rx) = mpsc::sync_channel(0);
|
let (unpark_tx, unpark_rx) = mpsc::sync_channel(0);
|
||||||
|
|
||||||
let pool = tokio_threadpool::Builder::new()
|
let pool = threadpool::Builder::new()
|
||||||
.custom_park(move |_| MyPark {
|
.custom_park(move |_| MyPark {
|
||||||
inner: DefaultPark::new(),
|
inner: DefaultPark::new(),
|
||||||
park_tx: park_tx.clone(),
|
park_tx: park_tx.clone(),
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![feature(async_await)]
|
#![feature(async_await)]
|
||||||
|
|
||||||
|
use tokio_executor::threadpool::*;
|
||||||
use tokio_test::*;
|
use tokio_test::*;
|
||||||
use tokio_threadpool::*;
|
|
||||||
|
|
||||||
use futures_core::ready;
|
use futures_core::ready;
|
||||||
use futures_util::future::poll_fn;
|
use futures_util::future::poll_fn;
|
||||||
@@ -16,8 +16,6 @@ use std::time::Duration;
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn basic() {
|
fn basic() {
|
||||||
let _ = ::env_logger::try_init();
|
|
||||||
|
|
||||||
let pool = Builder::new().pool_size(1).max_blocking(1).build();
|
let pool = Builder::new().pool_size(1).max_blocking(1).build();
|
||||||
|
|
||||||
let (tx1, rx1) = mpsc::channel();
|
let (tx1, rx1) = mpsc::channel();
|
||||||
@@ -41,8 +39,6 @@ fn basic() {
|
|||||||
|
|
||||||
#[test]
|
#[test]
|
||||||
fn other_executors_can_run_inside_blocking() {
|
fn other_executors_can_run_inside_blocking() {
|
||||||
let _ = ::env_logger::try_init();
|
|
||||||
|
|
||||||
let pool = Builder::new().pool_size(1).max_blocking(1).build();
|
let pool = Builder::new().pool_size(1).max_blocking(1).build();
|
||||||
|
|
||||||
let (tx, rx) = mpsc::channel();
|
let (tx, rx) = mpsc::channel();
|
||||||
@@ -1,8 +1,8 @@
|
|||||||
#![warn(rust_2018_idioms)]
|
#![warn(rust_2018_idioms)]
|
||||||
#![feature(async_await)]
|
#![feature(async_await)]
|
||||||
|
|
||||||
|
use tokio_executor::threadpool::*;
|
||||||
use tokio_sync::{mpsc, oneshot};
|
use tokio_sync::{mpsc, oneshot};
|
||||||
use tokio_threadpool::*;
|
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
+1
-1
@@ -23,7 +23,7 @@ categories = ["asynchronous", "network-programming", "filesystem"]
|
|||||||
|
|
||||||
[dependencies]
|
[dependencies]
|
||||||
tokio-io = { version = "=0.2.0-alpha.1", features = ["util"], path = "../tokio-io" }
|
tokio-io = { version = "=0.2.0-alpha.1", features = ["util"], path = "../tokio-io" }
|
||||||
tokio-threadpool = { version = "=0.2.0-alpha.1", path = "../tokio-threadpool" }
|
tokio-executor = { version = "=0.2.0-alpha.1", features = ["threadpool"], path = "../tokio-executor" }
|
||||||
|
|
||||||
futures-core-preview = "=0.3.0-alpha.18"
|
futures-core-preview = "=0.3.0-alpha.18"
|
||||||
futures-util-preview = "=0.3.0-alpha.18"
|
futures-util-preview = "=0.3.0-alpha.18"
|
||||||
|
|||||||
+6
-4
@@ -28,12 +28,12 @@
|
|||||||
//! type. Adaptions also extend to traits like `std::io::Read` where methods
|
//! type. Adaptions also extend to traits like `std::io::Read` where methods
|
||||||
//! return `std::io::Result`. Be warned that these adapted methods may return
|
//! return `std::io::Result`. Be warned that these adapted methods may return
|
||||||
//! `std::io::ErrorKind::WouldBlock` if a *worker* thread can not be converted
|
//! `std::io::ErrorKind::WouldBlock` if a *worker* thread can not be converted
|
||||||
//! to a *backup* thread immediately. See [tokio-threadpool] for more details
|
//! to a *backup* thread immediately. See [tokio-executor] for more details
|
||||||
//! of the threading model and [`blocking`].
|
//! of the threading model and [`blocking`].
|
||||||
//!
|
//!
|
||||||
//! [`blocking`]: https://docs.rs/tokio-threadpool/0.1/tokio_threadpool/fn.blocking.html
|
//! [`blocking`]: https://docs.rs/tokio-executor/0.2.0-alpha.2/tokio_executor/threadpool/fn.blocking.html
|
||||||
//! [`AsyncRead`]: https://docs.rs/tokio-io/0.1/tokio_io/trait.AsyncRead.html
|
//! [`AsyncRead`]: https://docs.rs/tokio-io/0.1/tokio_io/trait.AsyncRead.html
|
||||||
//! [tokio-threadpool]: https://docs.rs/tokio-threadpool/0.1/tokio_threadpool
|
//! [tokio-executor]: https://docs.rs/tokio-executor/0.2.0-alpha.2/tokio_executor/threadpool/index.html
|
||||||
|
|
||||||
mod create_dir;
|
mod create_dir;
|
||||||
mod create_dir_all;
|
mod create_dir_all;
|
||||||
@@ -85,7 +85,9 @@ fn blocking_io<F, T>(f: F) -> Poll<io::Result<T>>
|
|||||||
where
|
where
|
||||||
F: FnOnce() -> io::Result<T>,
|
F: FnOnce() -> io::Result<T>,
|
||||||
{
|
{
|
||||||
match tokio_threadpool::blocking(f) {
|
use tokio_executor::threadpool::blocking;
|
||||||
|
|
||||||
|
match blocking(f) {
|
||||||
Ready(Ok(v)) => Ready(v),
|
Ready(Ok(v)) => Ready(v),
|
||||||
Ready(Err(_)) => Ready(Err(blocking_err())),
|
Ready(Err(_)) => Ready(Err(blocking_err())),
|
||||||
Pending => Pending,
|
Pending => Pending,
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
use tokio_threadpool;
|
use tokio_executor::threadpool::Builder;
|
||||||
|
|
||||||
use self::tokio_threadpool::Builder;
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::io;
|
use std::io;
|
||||||
use std::sync::mpsc;
|
use std::sync::mpsc;
|
||||||
|
|||||||
@@ -1,85 +0,0 @@
|
|||||||
# 0.2.0-alpha.1 (August 8, 2019)
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
- Switch to `async`, `await`, and `std::future`.
|
|
||||||
|
|
||||||
# 0.1.14 (April 22, 2019)
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- Add `panic_handler` for customizing action taken on panic (#1052).
|
|
||||||
|
|
||||||
# 0.1.13 (March 22, 2019)
|
|
||||||
|
|
||||||
### Added
|
|
||||||
- `TypedExecutor` implementations (#993)
|
|
||||||
|
|
||||||
# 0.1.12 (March 1, 2019)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Documentation typos (#915).
|
|
||||||
|
|
||||||
### Changed
|
|
||||||
- Update crossbeam dependencies (#874).
|
|
||||||
|
|
||||||
# 0.1.11 (January 24, 2019)
|
|
||||||
|
|
||||||
### Fixed
|
|
||||||
- Drop incomplete tasks when threadpool is dropped (#722).
|
|
||||||
|
|
||||||
# 0.1.10 (January 6, 2019)
|
|
||||||
|
|
||||||
* Fix deadlock bug in `blocking` (#795).
|
|
||||||
* Introduce global task queue (#798).
|
|
||||||
* Use crossbeam's Parker / Unparker (#529).
|
|
||||||
* Panic if worker thread cannot be spawned (#826).
|
|
||||||
* Improve `blocking` API documentation (#789).
|
|
||||||
|
|
||||||
# 0.1.9 (November 21, 2018)
|
|
||||||
|
|
||||||
* Bump internal dependency versions (#746, #753).
|
|
||||||
* Internal refactors (#768, #769).
|
|
||||||
|
|
||||||
# 0.1.8 (October 23, 2018)
|
|
||||||
|
|
||||||
* Assign spawned tasks to random worker (#660).
|
|
||||||
* Worker threads no longer shutdown (#692).
|
|
||||||
* Reduce atomic ops in notifier (#702).
|
|
||||||
|
|
||||||
# 0.1.7 (September 27, 2018)
|
|
||||||
|
|
||||||
* Add ThreadPool::spawn_handle (#602, #604).
|
|
||||||
* Fix spawned future leak (#649).
|
|
||||||
|
|
||||||
# 0.1.6 (August 23, 2018)
|
|
||||||
|
|
||||||
* Misc performance improvements (#466, #468, #470, #475, #534)
|
|
||||||
* Documentation improvements (#450)
|
|
||||||
* Shutdown backup threads when idle (#489)
|
|
||||||
* Implement std::error::Error for error types (#511)
|
|
||||||
* Bugfix: handle num_cpus returning zero (#530).
|
|
||||||
|
|
||||||
# 0.1.5 (July 3, 2018)
|
|
||||||
|
|
||||||
* Fix race condition bug when threads are woken up (#459).
|
|
||||||
* Improve `BlockingError` message (#451).
|
|
||||||
|
|
||||||
# 0.1.4 (June 6, 2018)
|
|
||||||
|
|
||||||
* Fix bug that can occur with multiple pools in a process (#375).
|
|
||||||
|
|
||||||
# 0.1.3 (May 2, 2018)
|
|
||||||
|
|
||||||
* Add `blocking` annotation (#317).
|
|
||||||
|
|
||||||
# 0.1.2 (March 30, 2018)
|
|
||||||
|
|
||||||
* Add the ability to specify a custom thread parker.
|
|
||||||
|
|
||||||
# 0.1.1 (March 22, 2018)
|
|
||||||
|
|
||||||
* Handle futures that panic on the threadpool.
|
|
||||||
* Optionally support futures 0.2.
|
|
||||||
|
|
||||||
# 0.1.0 (March 09, 2018)
|
|
||||||
|
|
||||||
* Initial release
|
|
||||||
@@ -1,43 +0,0 @@
|
|||||||
[package]
|
|
||||||
name = "tokio-threadpool"
|
|
||||||
# When releasing to crates.io:
|
|
||||||
# - Remove path dependencies
|
|
||||||
# - Update html_root_url.
|
|
||||||
# - Update doc url
|
|
||||||
# - Cargo.toml
|
|
||||||
# - README.md
|
|
||||||
# - Update CHANGELOG.md.
|
|
||||||
# - Create "v0.2.x" git tag.
|
|
||||||
version = "0.2.0-alpha.1"
|
|
||||||
edition = "2018"
|
|
||||||
documentation = "https://docs.rs/tokio-threadpool/0.2.0-alpha.1/tokio_threadpool"
|
|
||||||
repository = "https://github.com/tokio-rs/tokio"
|
|
||||||
homepage = "https://github.com/tokio-rs/tokio"
|
|
||||||
license = "MIT"
|
|
||||||
authors = ["Tokio Contributors <[email protected]>"]
|
|
||||||
description = """
|
|
||||||
A task scheduler backed by a work-stealing thread pool.
|
|
||||||
"""
|
|
||||||
keywords = ["futures", "tokio"]
|
|
||||||
categories = ["concurrency", "asynchronous"]
|
|
||||||
|
|
||||||
[dependencies]
|
|
||||||
tokio-executor = { version = "=0.2.0-alpha.1", path = "../tokio-executor" }
|
|
||||||
tokio-sync = { version = "=0.2.0-alpha.1", path = "../tokio-sync" }
|
|
||||||
futures-core-preview = "=0.3.0-alpha.18"
|
|
||||||
futures-util-preview = "=0.3.0-alpha.18"
|
|
||||||
|
|
||||||
crossbeam-deque = "0.7.0"
|
|
||||||
crossbeam-queue = "0.1.0"
|
|
||||||
crossbeam-utils = "0.6.4"
|
|
||||||
num_cpus = "1.2"
|
|
||||||
slab = "0.4.1"
|
|
||||||
log = "0.4"
|
|
||||||
lazy_static = "1"
|
|
||||||
|
|
||||||
[dev-dependencies]
|
|
||||||
tokio = { version = "=0.2.0-alpha.1", path = "../tokio" }
|
|
||||||
tokio-test = { version = "=0.2.0-alpha.1", path = "../tokio-test" }
|
|
||||||
|
|
||||||
rand = "0.7"
|
|
||||||
env_logger = { version = "0.6", default-features = false }
|
|
||||||
@@ -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,14 +0,0 @@
|
|||||||
# Tokio Thread Pool
|
|
||||||
|
|
||||||
A library for scheduling execution of futures concurrently across a pool of
|
|
||||||
threads.
|
|
||||||
|
|
||||||
## 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
-2
@@ -44,8 +44,8 @@ rt-full = [
|
|||||||
"sync",
|
"sync",
|
||||||
"timer",
|
"timer",
|
||||||
"tokio-executor/current-thread",
|
"tokio-executor/current-thread",
|
||||||
|
"tokio-executor/threadpool",
|
||||||
"tokio-macros",
|
"tokio-macros",
|
||||||
"tokio-threadpool",
|
|
||||||
"tracing-core",
|
"tracing-core",
|
||||||
]
|
]
|
||||||
sync = ["tokio-sync"]
|
sync = ["tokio-sync"]
|
||||||
@@ -69,7 +69,6 @@ tokio-executor = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio
|
|||||||
tokio-macros = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-macros" }
|
tokio-macros = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-macros" }
|
||||||
tokio-net = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-net" }
|
tokio-net = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-net" }
|
||||||
tokio-sync = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-sync", features = ["async-traits"] }
|
tokio-sync = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-sync", features = ["async-traits"] }
|
||||||
tokio-threadpool = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-threadpool" }
|
|
||||||
tokio-tcp = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-tcp", features = ["async-traits"] }
|
tokio-tcp = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-tcp", features = ["async-traits"] }
|
||||||
tokio-udp = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-udp" }
|
tokio-udp = { version = "=0.2.0-alpha.1", optional = true, path = "../tokio-udp" }
|
||||||
tokio-timer = { version = "=0.3.0-alpha.1", optional = true, path = "../tokio-timer", features = ["async-traits"] }
|
tokio-timer = { version = "=0.3.0-alpha.1", optional = true, path = "../tokio-timer", features = ["async-traits"] }
|
||||||
|
|||||||
@@ -133,7 +133,7 @@
|
|||||||
//! [timer]: ../timer/index.html
|
//! [timer]: ../timer/index.html
|
||||||
//! [`Runtime`]: struct.Runtime.html
|
//! [`Runtime`]: struct.Runtime.html
|
||||||
//! [`Reactor`]: ../reactor/struct.Reactor.html
|
//! [`Reactor`]: ../reactor/struct.Reactor.html
|
||||||
//! [`ThreadPool`]: https://docs.rs/tokio-threadpool/0.1/tokio_threadpool/struct.ThreadPool.html
|
//! [`ThreadPool`]: https://docs.rs/tokio-executor/0.2.0-alpha.2/tokio_executor/threadpool/struct.ThreadPool.html
|
||||||
//! [`run`]: fn.run.html
|
//! [`run`]: fn.run.html
|
||||||
//! [idle]: struct.Runtime.html#method.shutdown_on_idle
|
//! [idle]: struct.Runtime.html#method.shutdown_on_idle
|
||||||
//! [`tokio::spawn`]: ../executor/fn.spawn.html
|
//! [`tokio::spawn`]: ../executor/fn.spawn.html
|
||||||
|
|||||||
@@ -1,7 +1,7 @@
|
|||||||
use super::{background, Inner, Runtime};
|
use super::{background, Inner, Runtime};
|
||||||
use crate::reactor::Reactor;
|
use crate::reactor::Reactor;
|
||||||
|
|
||||||
use tokio_threadpool::Builder as ThreadPoolBuilder;
|
use tokio_executor::threadpool;
|
||||||
use tokio_timer::clock::{self, Clock};
|
use tokio_timer::clock::{self, Clock};
|
||||||
use tokio_timer::timer::{self, Timer};
|
use tokio_timer::timer::{self, Timer};
|
||||||
|
|
||||||
@@ -51,7 +51,7 @@ use std::any::Any;
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
pub struct Builder {
|
pub struct Builder {
|
||||||
/// Thread pool specific builder
|
/// Thread pool specific builder
|
||||||
threadpool_builder: ThreadPoolBuilder,
|
threadpool_builder: threadpool::Builder,
|
||||||
|
|
||||||
/// The number of worker threads
|
/// The number of worker threads
|
||||||
core_threads: usize,
|
core_threads: usize,
|
||||||
@@ -68,7 +68,7 @@ impl Builder {
|
|||||||
pub fn new() -> Builder {
|
pub fn new() -> Builder {
|
||||||
let core_threads = num_cpus::get().max(1);
|
let core_threads = num_cpus::get().max(1);
|
||||||
|
|
||||||
let mut threadpool_builder = ThreadPoolBuilder::new();
|
let mut threadpool_builder = threadpool::Builder::new();
|
||||||
threadpool_builder.name_prefix("tokio-runtime-worker-");
|
threadpool_builder.name_prefix("tokio-runtime-worker-");
|
||||||
threadpool_builder.pool_size(core_threads);
|
threadpool_builder.pool_size(core_threads);
|
||||||
|
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ pub use self::task_executor::TaskExecutor;
|
|||||||
use background::Background;
|
use background::Background;
|
||||||
|
|
||||||
use tokio_executor::enter;
|
use tokio_executor::enter;
|
||||||
|
use tokio_executor::threadpool::ThreadPool;
|
||||||
use tokio_timer::timer;
|
use tokio_timer::timer;
|
||||||
|
|
||||||
use tracing_core as trace;
|
use tracing_core as trace;
|
||||||
@@ -37,7 +38,7 @@ pub struct Runtime {
|
|||||||
#[derive(Debug)]
|
#[derive(Debug)]
|
||||||
struct Inner {
|
struct Inner {
|
||||||
/// Task execution pool.
|
/// Task execution pool.
|
||||||
pool: tokio_threadpool::ThreadPool,
|
pool: ThreadPool,
|
||||||
|
|
||||||
/// Tracing dispatcher
|
/// Tracing dispatcher
|
||||||
trace: trace::Dispatch,
|
trace: trace::Dispatch,
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
use tokio_executor::SpawnError;
|
use tokio_executor::SpawnError;
|
||||||
use tokio_threadpool::Sender;
|
use tokio_executor::threadpool::Sender;
|
||||||
|
|
||||||
use std::future::Future;
|
use std::future::Future;
|
||||||
use std::pin::Pin;
|
use std::pin::Pin;
|
||||||
|
|||||||
Reference in New Issue
Block a user