mirror of
https://github.com/tokio-rs/tokio.git
synced 2026-08-25 00:00:18 +02:00
Support current_thread::spawn from task drop (#157)
Currently, the thread-local tracking the current thread executor is not set when a task is dropped. This means that one cannot spawn a new future from within the drop implementation of another future. This patch adds support for this by setting the thread-local before releasing a task. This implementation is a bit messy. It probably could be cleaned up, but this is being put off in favor of trying a more comprehensive reorganization once the current thread executor is feature complete.
This commit is contained in:
@@ -4,6 +4,7 @@ extern crate futures;
|
||||
|
||||
use tokio::executor::current_thread::{self, block_on_all, CurrentThread};
|
||||
|
||||
use std::any::Any;
|
||||
use std::cell::{Cell, RefCell};
|
||||
use std::rc::Rc;
|
||||
use std::thread;
|
||||
@@ -293,6 +294,48 @@ fn spawn_and_turn() {
|
||||
assert_eq!(2, cnt.get());
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn spawn_in_drop() {
|
||||
let mut current_thread = CurrentThread::new();
|
||||
|
||||
let (tx, rx) = oneshot::channel();
|
||||
|
||||
struct OnDrop<F: FnOnce()>(Option<F>);
|
||||
|
||||
impl<F: FnOnce()> Drop for OnDrop<F> {
|
||||
fn drop(&mut self) {
|
||||
(self.0.take().unwrap())();
|
||||
}
|
||||
}
|
||||
|
||||
struct MyFuture {
|
||||
_data: Box<Any>,
|
||||
}
|
||||
|
||||
impl Future for MyFuture {
|
||||
type Item = ();
|
||||
type Error = ();
|
||||
|
||||
fn poll(&mut self) -> Poll<(), ()> {
|
||||
Ok(().into())
|
||||
}
|
||||
}
|
||||
|
||||
current_thread.spawn({
|
||||
MyFuture {
|
||||
_data: Box::new(OnDrop(Some(move || {
|
||||
current_thread::spawn(lazy(move || {
|
||||
tx.send(()).unwrap();
|
||||
Ok(())
|
||||
}));
|
||||
}))),
|
||||
}
|
||||
});
|
||||
|
||||
current_thread.block_on(rx).unwrap();
|
||||
current_thread.run().unwrap();
|
||||
}
|
||||
|
||||
#[test]
|
||||
fn hammer_turn() {
|
||||
use futures::sync::mpsc;
|
||||
|
||||
Reference in New Issue
Block a user