mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-09-07 00:00:08 +02:00
executor: add executor::exit (#1155)
This allows blocking on executors from within a `threadpool::blocking` call.
This commit is contained in:
committed by
Carl Lerche
parent
5dcb379f6d
commit
cad0c35623
@@ -21,7 +21,7 @@ keywords = ["futures", "tokio"]
|
||||
categories = ["concurrency", "asynchronous"]
|
||||
|
||||
[dependencies]
|
||||
tokio-executor = "0.1.7"
|
||||
tokio-executor = { path = "../tokio-executor", version = "0.1.7" }
|
||||
futures = "0.1.19"
|
||||
crossbeam-deque = "0.7.0"
|
||||
crossbeam-queue = "0.1.0"
|
||||
|
||||
@@ -1,6 +1,7 @@
|
||||
use worker::Worker;
|
||||
|
||||
use futures::Poll;
|
||||
use tokio_executor;
|
||||
|
||||
use std::error::Error;
|
||||
use std::fmt;
|
||||
@@ -142,8 +143,11 @@ where
|
||||
// If the transition cannot happen, exit early
|
||||
try_ready!(res);
|
||||
|
||||
// Currently in blocking mode, so call the inner closure
|
||||
let ret = f();
|
||||
// Currently in blocking mode, so call the inner closure.
|
||||
//
|
||||
// "Exit" the current executor in case the blocking function wants
|
||||
// to call a different executor.
|
||||
let ret = tokio_executor::exit(move || f());
|
||||
|
||||
// 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.
|
||||
|
||||
@@ -1,5 +1,7 @@
|
||||
#![doc(html_root_url = "https://docs.rs/tokio-threadpool/0.1.14")]
|
||||
#![deny(warnings, missing_docs, missing_debug_implementations)]
|
||||
// Our MSRV doesn't allow us to fix these warnings yet
|
||||
#![allow(rust_2018_idioms)]
|
||||
|
||||
//! A work-stealing based thread pool for executing futures.
|
||||
//!
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
extern crate tokio_executor;
|
||||
extern crate tokio_threadpool;
|
||||
|
||||
extern crate env_logger;
|
||||
@@ -44,6 +45,28 @@ fn basic() {
|
||||
rx2.recv().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn other_executors_can_run_inside_blocking() {
|
||||
let _ = ::env_logger::try_init();
|
||||
|
||||
let pool = Builder::new().pool_size(1).max_blocking(1).build();
|
||||
|
||||
let (tx, rx) = mpsc::channel();
|
||||
|
||||
pool.spawn(lazy(move || {
|
||||
let res = blocking(|| {
|
||||
let _e = tokio_executor::enter().expect("nested blocking enter");
|
||||
tx.send(()).unwrap();
|
||||
})
|
||||
.unwrap();
|
||||
|
||||
assert!(res.is_ready());
|
||||
Ok(().into())
|
||||
}));
|
||||
|
||||
rx.recv().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn notify_task_on_capacity() {
|
||||
const BLOCKING: usize = 10;
|
||||
|
||||
Reference in New Issue
Block a user