nrf/gpiote: fix irq race condition

The interrupt could fire between checking if sense=disabled and registering the waker,
in which case the future would get stuck.
This commit is contained in:
Dario Nieuwenhuis
2021-03-27 02:08:01 +01:00
parent 4ce46df160
commit 1c9f98e1b6
2 changed files with 10 additions and 15 deletions

View File

@ -395,9 +395,8 @@ pub struct PortInputFuture<'a> {
impl<'a> Drop for PortInputFuture<'a> {
fn drop(&mut self) {
unsafe { AnyPin::steal(self.pin_port) }
.conf()
.modify(|_, w| w.sense().disabled());
let pin = unsafe { AnyPin::steal(self.pin_port) };
pin.conf().modify(|_, w| w.sense().disabled());
}
}
@ -405,18 +404,13 @@ impl<'a> Future for PortInputFuture<'a> {
type Output = ();
fn poll(self: core::pin::Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<Self::Output> {
let dis = unsafe { AnyPin::steal(self.pin_port) }
.conf()
.read()
.sense()
.is_disabled();
if dis {
return Poll::Ready(());
}
PORT_WAKERS[self.pin_port as usize].register(cx.waker());
Poll::Pending
let pin = unsafe { AnyPin::steal(self.pin_port) };
if pin.conf().read().sense().is_disabled() {
Poll::Ready(())
} else {
Poll::Pending
}
}
}