mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-22 00:00:11 +02:00
Implement a Send Handle for the single-threaded Runtime (#340)
Implement a Send'able Handle for the single-threaded `Runtime` and `CurrentThread` executor to spawn new tasks from other threads.
This commit is contained in:
committed by
Carl Lerche
parent
c07a7b26d3
commit
0d41ba7a08
@@ -17,11 +17,9 @@
|
||||
//!
|
||||
//! # Spawning from other threads
|
||||
//!
|
||||
//! By default, [`current_thread::Runtime`][rt] does not provide a way to spawn
|
||||
//! tasks from other threads. However, this can be accomplished by using a
|
||||
//! [`mpsc::channel`][chan]. To do so, create a channel to send the task, then
|
||||
//! spawn a task on [`current_thread::Runtime`][rt] that consumes the channel
|
||||
//! messages and spawns new tasks for them.
|
||||
//! While [`current_thread::Runtime`][rt] does not implement `Send` and cannot
|
||||
//! safely be moved to other threads, it provides a `Handle` that can be sent
|
||||
//! to other threads and allows to spawn new tasks from there.
|
||||
//!
|
||||
//! For example:
|
||||
//!
|
||||
@@ -30,17 +28,15 @@
|
||||
//! # extern crate futures;
|
||||
//! use tokio::runtime::current_thread::Runtime;
|
||||
//! use tokio::prelude::*;
|
||||
//! use futures::sync::mpsc;
|
||||
//! use std::thread;
|
||||
//!
|
||||
//! # fn main() {
|
||||
//! let mut runtime = Runtime::new().unwrap();
|
||||
//! let (tx, rx) = mpsc::channel(128);
|
||||
//! # tx.send(future::ok(()));
|
||||
//! let handle = runtime.handle();
|
||||
//!
|
||||
//! runtime.spawn(rx.for_each(|task| {
|
||||
//! tokio::spawn(task);
|
||||
//! Ok(())
|
||||
//! }).map_err(|e| panic!("channel error")));
|
||||
//! thread::spawn(move || {
|
||||
//! handle.spawn(future::ok(()));
|
||||
//! }).join().unwrap();
|
||||
//!
|
||||
//! # /*
|
||||
//! runtime.run().unwrap();
|
||||
@@ -69,4 +65,4 @@
|
||||
|
||||
mod runtime;
|
||||
|
||||
pub use self::runtime::Runtime;
|
||||
pub use self::runtime::{Runtime, Handle};
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
use executor::current_thread::{self, CurrentThread};
|
||||
use executor::current_thread::Handle as ExecutorHandle;
|
||||
|
||||
use tokio_reactor::{self, Reactor};
|
||||
use tokio_timer::timer::{self, Timer};
|
||||
@@ -21,6 +22,23 @@ pub struct Runtime {
|
||||
executor: CurrentThread<Timer<Reactor>>,
|
||||
}
|
||||
|
||||
/// Handle to spawn a future on the corresponding `CurrentThread` runtime instance
|
||||
#[derive(Debug, Clone)]
|
||||
pub struct Handle(ExecutorHandle);
|
||||
|
||||
impl Handle {
|
||||
/// Spawn a future onto the `CurrentThread` runtime instance corresponding to this handle
|
||||
///
|
||||
/// # Panics
|
||||
///
|
||||
/// This function panics if the spawn fails. Failure occurs if the `CurrentThread`
|
||||
/// instance of the `Handle` does not exist anymore.
|
||||
pub fn spawn<F>(&self, future: F) -> Result<(), tokio_executor::SpawnError>
|
||||
where F: Future<Item = (), Error = ()> + Send + 'static {
|
||||
self.0.spawn(future)
|
||||
}
|
||||
}
|
||||
|
||||
/// Error returned by the `run` function.
|
||||
#[derive(Debug)]
|
||||
pub struct RunError {
|
||||
@@ -48,6 +66,14 @@ impl Runtime {
|
||||
Ok(runtime)
|
||||
}
|
||||
|
||||
/// Get a new handle to spawn futures on the single-threaded Tokio runtime
|
||||
///
|
||||
/// Different to the runtime itself, the handle can be sent to different
|
||||
/// threads.
|
||||
pub fn handle(&self) -> Handle {
|
||||
Handle(self.executor.handle().clone())
|
||||
}
|
||||
|
||||
/// Spawn a future onto the single-threaded Tokio runtime.
|
||||
///
|
||||
/// See [module level][mod] documentation for more details.
|
||||
@@ -124,7 +150,7 @@ impl Runtime {
|
||||
fn enter<F, R>(&mut self, f: F) -> R
|
||||
where F: FnOnce(&mut current_thread::Entered<Timer<Reactor>>) -> R
|
||||
{
|
||||
let Runtime { ref reactor_handle, ref timer_handle, ref mut executor } = *self;
|
||||
let Runtime { ref reactor_handle, ref timer_handle, ref mut executor, .. } = *self;
|
||||
|
||||
// Binds an executor to this thread
|
||||
let mut enter = tokio_executor::enter().expect("Multiple executors at once");
|
||||
|
||||
Reference in New Issue
Block a user