Skip to content

Commit

Permalink
adding support for no_std executor
Browse files Browse the repository at this point in the history
  • Loading branch information
Richard authored and Richard committed Mar 25, 2020
1 parent daffa0f commit 907faac
Show file tree
Hide file tree
Showing 6 changed files with 78 additions and 9 deletions.
7 changes: 4 additions & 3 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -19,13 +19,14 @@ runtime_asyncstd = [
runtime_tokio = [
"tokio"
]
# runtime_nostd = [
# "core"
# ]
runtime_nostd = [
"executor"
]

[dependencies]
bastion-executor = { version = "0.3", optional = true, features = [] }
async-std = { version = "1.3", optional = true, features = ["unstable"] }
tokio = { version = "0.2", optional = true, features = ["rt-core", "blocking"] }
# core = { package = "core-futures-tls", version = "0.1.0", optional = true }
lightproc = { version = "0.3.4", optional = true }
executor = { version = "0.7.0", optional = true }
3 changes: 1 addition & 2 deletions ci.sh
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,4 @@
cargo test --features=runtime_bastion
cargo test --features=runtime_asyncstd
cargo test --features=runtime_tokio
# Disabled until we have async / await in no_std
# cargo test --features=runtime_nostd
cargo test --features=runtime_nostd
39 changes: 38 additions & 1 deletion src/executors.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
use crate::AgnostikExecutor;
use crate::join_handle::{InnerJoinHandle, JoinHandle};
use std::future::Future;
use core::future::Future;

#[cfg(feature = "runtime_asyncstd")]
pub(crate) struct AsyncStdExecutor;
Expand Down Expand Up @@ -132,3 +132,40 @@ impl AgnostikExecutor for BastionExecutor {
bastion_executor::run::run(future, ProcStack::default())
}
}

#[cfg(feature = "runtime_nostd")]
pub(crate) struct NoStdExecutor;

#[cfg(feature = "runtime_nostd")]
impl NoStdExecutor {
pub fn new() -> Self {
NoStdExecutor {}
}
}

#[cfg(feature = "runtime_nostd")]
impl AgnostikExecutor for NoStdExecutor {
fn spawn<F, T>(&self, _future: F) -> JoinHandle<T>
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
panic!("no threads on no_std environments")
}

fn spawn_blocking<F, T>(&self, _task: F) -> JoinHandle<T>
where
F: FnOnce() -> T + Send + 'static,
T: Send + 'static,
{
panic!("no threads on no_std environments")
}

fn block_on<F, T>(&self, future: F) -> T
where
F: Future<Output = T> + Send + 'static,
T: Send + 'static,
{
executor::block_on(future)
}
}
10 changes: 9 additions & 1 deletion src/join_handle.rs
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//! Generic join handle type.

use std::{
use core::{
future::Future,
pin::Pin,
task::{Context, Poll},
Expand All @@ -22,13 +22,20 @@ use tokio::task::JoinHandle as TokioHandle;
/// agnostik will panic if the task failed to execute.
pub struct JoinHandle<R>(pub(crate) InnerJoinHandle<R>);

pub struct NoStdJoinHandle<T> {
__phantom: core::marker::PhantomData<T>
}

pub(crate) enum InnerJoinHandle<R> {
#[cfg(feature = "runtime_bastion")]
Bastion(RecoverableHandle<R>),
#[cfg(feature = "runtime_asyncstd")]
AsyncStd(AsyncStdHandle<R>),
#[cfg(feature = "runtime_tokio")]
Tokio(TokioHandle<R>),
#[cfg(feature = "runtime_nostd")]
#[allow(dead_code)]
NoStd(NoStdJoinHandle<R>),
}

impl<R> Future for JoinHandle<R>
Expand All @@ -49,6 +56,7 @@ where
InnerJoinHandle::Tokio(ref mut handle) => Pin::new(handle)
.poll(cx)
.map(|val| val.expect("task failed to execute")),
InnerJoinHandle::NoStd(_) => panic!("no threads on no_std environments"),
}
}
}
14 changes: 12 additions & 2 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,7 @@
//! - `Agnostik::async_std()` for async std
//! - `Agnostik::tokio()` for tokio. **Warning:** See "How to use tokio runtime"
//! - `Agnostik::tokio_with_runtime(runtime)` if you want to use your own `tokio::runtime::Runtime` object. **Warning:** See "How to use tokio runtime"
//! - `Agnostik::no_std()` (coming soon) to create an exeutor that works in a nostd environment
//! - `Agnostik::no_std()` (coming soon) to create an executor that works in a nostd environment
//!
//! ### How to use tokio runtime
//!
Expand Down Expand Up @@ -125,12 +125,13 @@
//!
//! You can replace 1 and 2 with `Agnostik::tokio()`, because this method call will
//! create a Runtime object using `Runtime::new()`.
#![cfg_attr(feature="runtime_nostd", no_std)]

mod executors;
pub mod join_handle;

use join_handle::JoinHandle;
use std::future::Future;
use core::future::Future;

/// This trait represents a generic executor that can spawn a future, spawn a blocking task,
/// and wait for a future to finish.
Expand Down Expand Up @@ -207,6 +208,15 @@ impl Agnostik {
pub fn tokio_with_runtime(runtime: tokio::runtime::Runtime) -> impl AgnostikExecutor {
executors::TokioExecutor::with_runtime(runtime)
}

#[cfg(feature = "runtime_nostd")]
/// Returns an [AgnostikExecutor], that will use a no_std executor from [executor] package
///
/// [executor]: https://docs.rs/executor
/// [AgnostikExecutor]: ../trait.AgnostikExecutor.html
pub fn no_std() -> impl AgnostikExecutor {
executors::NoStdExecutor::new()
}
}

#[allow(unused)]
Expand Down
14 changes: 14 additions & 0 deletions tests/no_std.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
pub use agnostik::prelude::*;

#[cfg(feature = "runtime_nostd")]
#[test]
fn test_tokio() {
let agnostik = Agnostik::no_std();
agnostik.block_on(async {
let mut i = 0;
while i < 5 {
println!("Counting from no_std: {}", i);
i+=1;
}
});
}

0 comments on commit 907faac

Please sign in to comment.