#![no_std]
#![feature(futures_api, pin, const_fn, nll, cell_update, alloc, arbitrary_self_types)]
#![warn(missing_docs, missing_debug_implementations)]
extern crate futures;
#[macro_use]
extern crate pin_utils;
extern crate spin;
#[cfg(test)]
#[macro_use]
extern crate std;
#[cfg(alloc)]
extern crate alloc;
use futures::prelude::*;
use core::sync::atomic;
use futures::future::{FutureObj, LocalFutureObj};
use futures::task::{LocalSpawn, LocalWaker, Poll, Spawn, SpawnError};
#[cfg(alloc)]
pub mod threaded;
pub mod cached;
mod wake;
use self::wake::DumbWake;
#[derive(Debug, Default)]
pub struct DumbExec {
_opaque: (),
}
impl DumbExec {
pub fn new() -> DumbExec {
DumbExec { _opaque: () }
}
pub fn run<F: Future>(&self, future: F) -> F::Output {
pin_mut!(future);
let local_waker = unsafe { LocalWaker::new(DumbWake::get()) };
loop {
match Future::poll(future.as_mut(), &local_waker) {
Poll::Pending => atomic::spin_loop_hint(),
Poll::Ready(v) => return v,
}
}
}
}
impl Spawn for DumbExec {
#[inline]
fn spawn_obj(&mut self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
self.run(future);
Ok(())
}
}
impl<'a> Spawn for &'a DumbExec {
#[inline]
fn spawn_obj(&mut self, future: FutureObj<'static, ()>) -> Result<(), SpawnError> {
self.run(future);
Ok(())
}
}
impl LocalSpawn for DumbExec {
#[inline]
fn spawn_local_obj(&mut self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
self.run(future);
Ok(())
}
}
impl<'a> LocalSpawn for &'a DumbExec {
#[inline]
fn spawn_local_obj(&mut self, future: LocalFutureObj<'static, ()>) -> Result<(), SpawnError> {
self.run(future);
Ok(())
}
}
#[cfg(test)]
mod tests {
use super::DumbExec;
use futures::prelude::*;
#[test]
fn it_works() {
let exec = DumbExec::new();
assert_eq!(exec.run(future::ready(4)), 4);
assert_eq!(exec.run(future::lazy(|_| 4)), 4);
assert_eq!(
exec.run(
future::lazy(|_| 2)
.join(future::lazy(|_| 2))
.map(|(x, y)| x + y)
),
4
);
}
}