Я пытаюсь найти простой способ реализации черты Future
из будущего ящика, версия 0.2.1:
extern crate futures;
use futures::executor::ThreadPool;
use futures::prelude::*;
use futures::task::Context;
use std::{thread, time::Duration};
struct SendThree {
firstTime: bool,
}
impl Future for SendThree {
type Item = u32;
type Error = Never;
fn poll(&mut self, ctx: &mut Context) -> Result<Async<Self::Item>, Never> {
if self.firstTime {
self.firstTime = false;
thread::spawn(move || {
thread::sleep(Duration::from_millis(10));
ctx.waker().wake();
});
Ok(Async::Pending)
} else {
Ok(Async::Ready(3))
}
}
}
fn main() {
let mut fut = SendThree { firstTime: true };
let mut executor: ThreadPool = ThreadPool::new().unwrap();
let result = executor.run(fut).unwrap();
println!("{}", result);
}
детская площадка
Моя проблема в том, что переменная Context
не Send
, поэтому я не могу вызвать wake
из другого потока:
error[E0277]: the trait bound `futures::executor::Executor: std::marker::Send` is not satisfied
--> src/main.rs:19:13
|
19 | thread::spawn(move || {
| ^^^^^^^^^^^^^ `futures::executor::Executor` cannot be sent between threads safely
|
= help: the trait `std::marker::Send` is not implemented for `futures::executor::Executor`
= note: required because of the requirements on the impl of `std::marker::Send` for `&mut futures::executor::Executor`
= note: required because it appears within the type `std::option::Option<&mut futures::executor::Executor>`
= note: required because it appears within the type `futures::task::Context<'_>`
= note: required because of the requirements on the impl of `std::marker::Send` for `&mut futures::task::Context<'_>`
= note: required because it appears within the type `[closure@src/main.rs:19:27: 22:14 ctx:&mut futures::task::Context<'_>]`
= note: required by `std::thread::spawn`
Если я изменю код на это, он будет работать, но я могуthread::sleep
без блокировки:
if self.firstTime {
self.firstTime = false;
ctx.waker().wake();
Ok(Async::Pending)
}
Есть ли идиоматический способ реализовать это?