ove/async_runtime/
semaphore.rs1use core::future::poll_fn;
11use core::task::Poll;
12
13use embassy_sync::waitqueue::AtomicWaker;
14
15use crate::error::{Error, Result};
16use crate::sync::Semaphore;
17
18pub struct AsyncSemaphore {
20 inner: Semaphore,
21 waker: AtomicWaker,
22}
23
24unsafe impl Send for AsyncSemaphore {}
28unsafe impl Sync for AsyncSemaphore {}
29
30impl AsyncSemaphore {
31 pub const fn new(inner: Semaphore) -> 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(sem_notify_trampoline),
42 &self.waker as *const AtomicWaker as *mut core::ffi::c_void,
43 )
44 }
45 }
46
47 pub async fn acquire(&'static self) -> Result<()> {
49 poll_fn(|cx| {
50 match self.inner.try_acquire() {
51 Ok(()) => return Poll::Ready(Ok(())),
52 Err(Error::WouldBlock) | Err(Error::Timeout) => {}
53 Err(e) => return Poll::Ready(Err(e)),
54 }
55 self.waker.register(cx.waker());
56 match self.inner.try_acquire() {
57 Ok(()) => Poll::Ready(Ok(())),
58 Err(Error::WouldBlock) | Err(Error::Timeout) => Poll::Pending,
59 Err(e) => Poll::Ready(Err(e)),
60 }
61 })
62 .await
63 }
64
65 #[inline]
66 pub fn inner(&self) -> &Semaphore {
67 &self.inner
68 }
69}
70
71unsafe extern "C" fn sem_notify_trampoline(user_data: *mut core::ffi::c_void) {
72 let waker = unsafe { &*(user_data as *const AtomicWaker) };
73 waker.wake();
74}