ove/async_runtime/
eventgroup.rs1use core::future::poll_fn;
11use core::task::Poll;
12
13use embassy_sync::waitqueue::AtomicWaker;
14
15use crate::error::{Error, Result};
16use crate::eventgroup::{EventGroup, WaitFlags};
17
18pub struct AsyncEventGroup {
20 inner: EventGroup,
21 waker: AtomicWaker,
22}
23
24unsafe impl Send for AsyncEventGroup {}
28unsafe impl Sync for AsyncEventGroup {}
29
30impl AsyncEventGroup {
31 pub const fn new(inner: EventGroup) -> Self {
32 Self {
33 inner,
34 waker: AtomicWaker::new(),
35 }
36 }
37
38 pub fn arm(&'static self) -> Result<()> {
39 unsafe {
40 self.inner.set_notify(
41 Some(eg_notify_trampoline),
42 &self.waker as *const AtomicWaker as *mut core::ffi::c_void,
43 )
44 }
45 }
46
47 pub async fn wait_bits(&'static self, mask: u32, flags: WaitFlags) -> Result<u32> {
50 poll_fn(|cx| {
51 match self.inner.try_wait_bits(mask, flags) {
52 Ok(v) => return Poll::Ready(Ok(v)),
53 Err(Error::WouldBlock) | Err(Error::Timeout) => {}
54 Err(e) => return Poll::Ready(Err(e)),
55 }
56 self.waker.register(cx.waker());
57 match self.inner.try_wait_bits(mask, flags) {
58 Ok(v) => Poll::Ready(Ok(v)),
59 Err(Error::WouldBlock) | Err(Error::Timeout) => Poll::Pending,
60 Err(e) => Poll::Ready(Err(e)),
61 }
62 })
63 .await
64 }
65
66 #[inline]
67 pub fn inner(&self) -> &EventGroup {
68 &self.inner
69 }
70}
71
72unsafe extern "C" fn eg_notify_trampoline(user_data: *mut core::ffi::c_void) {
73 let waker = unsafe { &*(user_data as *const AtomicWaker) };
74 waker.wake();
75}