Skip to content

Commit 82c69a2

Browse files
committed
Add notify
1 parent 0d1a512 commit 82c69a2

2 files changed

Lines changed: 88 additions & 0 deletions

File tree

pixie-uefi/src/os/mod.rs

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@ pub mod input;
1818
mod logger;
1919
pub mod memory;
2020
pub mod net;
21+
mod notify;
2122
mod send_wrapper;
2223
mod timer;
2324
pub mod ui;

pixie-uefi/src/os/notify.rs

Lines changed: 87 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,87 @@
1+
use alloc::sync::Arc;
2+
use alloc::vec::Vec;
3+
use core::future::Future;
4+
use core::pin::Pin;
5+
use core::task::{Context, Poll, Waker};
6+
7+
use spin::Mutex;
8+
9+
struct NotifyInner {
10+
vec: Vec<Arc<Mutex<NotifiedInner>>>,
11+
}
12+
13+
pub struct Notify {
14+
inner: Mutex<NotifyInner>,
15+
}
16+
17+
impl Notify {
18+
pub fn new() -> Self {
19+
let inner = Mutex::new(NotifyInner { vec: Vec::new() });
20+
Notify { inner }
21+
}
22+
23+
pub fn wait(&self) -> Notified<'_> {
24+
let mut n = self.inner.lock();
25+
let inner = Arc::new(Mutex::new(NotifiedInner {
26+
notified: false,
27+
position: n.vec.len(),
28+
waker: None,
29+
}));
30+
n.vec.push(inner.clone());
31+
Notified {
32+
notify: self,
33+
inner,
34+
}
35+
}
36+
37+
pub fn notify_all(&self) {
38+
let mut n = self.inner.lock();
39+
for inner in n.vec.drain(..) {
40+
let mut guard = inner.lock();
41+
guard.notified = true;
42+
if let Some(waker) = guard.waker.take() {
43+
waker.wake();
44+
}
45+
}
46+
}
47+
}
48+
49+
struct NotifiedInner {
50+
notified: bool,
51+
position: usize,
52+
waker: Option<Waker>,
53+
}
54+
55+
pub struct Notified<'a> {
56+
notify: &'a Notify,
57+
inner: Arc<Mutex<NotifiedInner>>,
58+
}
59+
60+
impl Future for Notified<'_> {
61+
type Output = ();
62+
63+
fn poll(self: Pin<&mut Self>, cx: &mut Context<'_>) -> Poll<()> {
64+
let mut guard = self.inner.lock();
65+
if guard.notified {
66+
Poll::Ready(())
67+
} else {
68+
guard.waker = Some(cx.waker().clone());
69+
Poll::Pending
70+
}
71+
}
72+
}
73+
74+
impl Drop for Notified<'_> {
75+
fn drop(&mut self) {
76+
let mut n = self.notify.inner.lock();
77+
let i = self.inner.lock();
78+
if i.notified {
79+
return;
80+
}
81+
n.vec.swap_remove(i.position);
82+
if let Some(swapped) = n.vec.get(i.position) {
83+
let mut swapped_guard = swapped.lock();
84+
swapped_guard.position = i.position;
85+
}
86+
}
87+
}

0 commit comments

Comments
 (0)