Skip to content

Commit

Permalink
block_on method
Browse files Browse the repository at this point in the history
  • Loading branch information
ivmarkov committed Oct 8, 2023
1 parent 4a0dfc4 commit cc3585e
Show file tree
Hide file tree
Showing 2 changed files with 31 additions and 0 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0
* CAN driver: support for pulling alerts in blocking and async mode
* UART driver: support for pulling UART events
* `task` and `interrupt` modules: new submodule in each - `asynch` - featuring a signal/notification-like synchronization primitive
* `task` module: `block_on` method capable of executing a future on the current thread
* `task` module: new sub-module - `queue` for the FreeRTOS `queue` synchonization primitive
* `task` module: new sub-module - `notification` - a more ergonomic API around the FreeRTOS task notification API
which was already exposed via the `task::notify` and `task::wait_notification` APIs
Expand Down
30 changes: 30 additions & 0 deletions src/task.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
use core::cell::Cell;
use core::future::Future;
use core::num::NonZeroU32;
use core::pin::pin;
use core::ptr::{self, NonNull};
use core::sync::atomic::{AtomicBool, Ordering};
use core::task::{Context, Poll};

use esp_idf_sys::*;

Expand Down Expand Up @@ -214,6 +217,33 @@ pub fn get_idle_task(core: crate::cpu::Core) -> TaskHandle_t {
}
}

/// Executes the supplied future on the current thread, thus blocking it until the future becomes ready.
pub fn block_on<F>(mut fut: F) -> F::Output
where
F: Future,
{
log::trace!("block_on(): started");

let notification = notification::Notification::new();

let mut fut = pin!(fut);

let waker = notification.notifier().into();

let mut cx = Context::from_waker(&waker);

let res = loop {
match fut.as_mut().poll(&mut cx) {
Poll::Ready(res) => break res,
Poll::Pending => notification.wait_any(),
}
};

log::trace!("block_on(): finished");

res
}

#[cfg(esp_idf_comp_pthread_enabled)]
pub mod thread {
use core::ffi::CStr;
Expand Down

0 comments on commit cc3585e

Please sign in to comment.