embassy-rp: defensive change to ensure wakers are registered

This change ensures that wakers are registered PRIOR to checking status
in i2c `wait_on` helpers.
This commit is contained in:
James Munns 2025-04-03 19:01:00 +02:00
parent 99536219a3
commit 72832c1550
2 changed files with 8 additions and 4 deletions

View File

@ -114,17 +114,19 @@ impl<'d, T: Instance> I2c<'d, T, Async> {
} }
/// Calls `f` to check if we are ready or not. /// Calls `f` to check if we are ready or not.
/// If not, `g` is called once the waker is set (to eg enable the required interrupts). /// If not, `g` is called once(to eg enable the required interrupts).
/// The waker will always be registered prior to calling `f`.
async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U
where where
F: FnMut(&mut Self) -> Poll<U>, F: FnMut(&mut Self) -> Poll<U>,
G: FnMut(&mut Self), G: FnMut(&mut Self),
{ {
future::poll_fn(|cx| { future::poll_fn(|cx| {
// Register prior to checking the condition
T::waker().register(cx.waker());
let r = f(self); let r = f(self);
if r.is_pending() { if r.is_pending() {
T::waker().register(cx.waker());
g(self); g(self);
} }
r r

View File

@ -159,7 +159,8 @@ impl<'d, T: Instance> I2cSlave<'d, T> {
} }
/// Calls `f` to check if we are ready or not. /// Calls `f` to check if we are ready or not.
/// If not, `g` is called once the waker is set (to eg enable the required interrupts). /// If not, `g` is called once(to eg enable the required interrupts).
/// The waker will always be registered prior to calling `f`.
#[inline(always)] #[inline(always)]
async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U async fn wait_on<F, U, G>(&mut self, mut f: F, mut g: G) -> U
where where
@ -167,10 +168,11 @@ impl<'d, T: Instance> I2cSlave<'d, T> {
G: FnMut(&mut Self), G: FnMut(&mut Self),
{ {
future::poll_fn(|cx| { future::poll_fn(|cx| {
// Register prior to checking the condition
T::waker().register(cx.waker());
let r = f(self); let r = f(self);
if r.is_pending() { if r.is_pending() {
T::waker().register(cx.waker());
g(self); g(self);
} }