Skip to content

Commit

Permalink
Replace Option with a null waker
Browse files Browse the repository at this point in the history
  • Loading branch information
bugadani committed Nov 18, 2024
1 parent f83bd19 commit b014d1c
Showing 1 changed file with 19 additions and 12 deletions.
31 changes: 19 additions & 12 deletions esp-hal/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -573,38 +573,45 @@ pub fn init(config: Config) -> Peripherals {

/// Asynchronous utilities.
pub mod asynch {
use core::task::Waker;
use core::{
ptr,
task::{RawWaker, RawWakerVTable, Waker},
};

use crate::sync::Locked;

// A no-op vtable used to initialize an AtomicWaker.
static VTABLE: RawWakerVTable = RawWakerVTable::new(
|_| RawWaker::new(ptr::null(), &VTABLE),
|_| {},
|_| {},
|_| {},
);

/// Utility struct to register and wake a waker.
pub struct AtomicWaker {
waker: Locked<Option<Waker>>,
waker: Locked<Waker>,
}

impl AtomicWaker {
/// Create a new `AtomicWaker`.
pub const fn new() -> Self {
// TODO: replace with `Waker::noop` once stable
let raw_waker = RawWaker::new(ptr::null(), &VTABLE);
let waker = unsafe { Waker::from_raw(raw_waker) };
Self {
waker: Locked::new(None),
waker: Locked::new(waker),
}
}

/// Register a waker. Overwrites the previous waker, if any.
pub fn register(&self, w: &Waker) {
self.waker.with(|waker| match waker {
Some(w2) if w2.will_wake(w) => {}
_ => *waker = Some(w.clone()),
})
self.waker.with(|waker| waker.clone_from(w))
}

/// Wake the registered waker, if any.
pub fn wake(&self) {
self.waker.with(|waker| {
if let Some(w) = waker {
w.wake_by_ref();
}
})
self.waker.with(|waker| waker.wake_by_ref())
}
}
}

0 comments on commit b014d1c

Please sign in to comment.