compio_io\compat/
waker_array.rs1use std::{
2 mem::ManuallyDrop,
3 sync::Arc,
4 task::{RawWaker, RawWakerVTable, Wake, Waker},
5};
6
7pub struct WakerArrayRef<'a, const N: usize>([Option<&'a Waker>; N]);
10
11impl<'a, const N: usize> WakerArrayRef<'a, N> {
12 const VTABLE: &'static RawWakerVTable =
13 &RawWakerVTable::new(Self::clone, Self::wake, Self::wake_by_ref, Self::drop);
14
15 pub fn new(wakers: [Option<&'a Waker>; N]) -> Self {
18 Self(wakers)
19 }
20
21 pub fn with<F, R>(&self, f: F) -> R
23 where
24 F: FnOnce(&Waker) -> R,
25 {
26 let waker = unsafe { Waker::new(self as *const Self as *const (), Self::VTABLE) };
27 f(&waker)
28 }
29
30 fn wake_impl(&self) {
31 for waker in self.0.iter().flatten() {
32 waker.wake_by_ref();
33 }
34 }
35
36 fn to_owned(&self) -> WakerArray<N> {
37 WakerArray(self.0.map(|waker| waker.cloned()))
38 }
39
40 unsafe fn from_raw<'s>(ptr: *const ()) -> &'s Self {
41 unsafe { &*ptr.cast::<Self>() }
42 }
43
44 unsafe fn clone(ptr: *const ()) -> RawWaker {
45 let this = unsafe { Self::from_raw(ptr) };
46 let owned = this.to_owned();
47 let waker = ManuallyDrop::new(Waker::from(Arc::new(owned)));
48 RawWaker::new(waker.data(), waker.vtable())
49 }
50
51 unsafe fn wake(_: *const ()) {
52 unreachable!("WakerArrayRef will only be accessed with reference")
53 }
54
55 unsafe fn wake_by_ref(ptr: *const ()) {
56 unsafe { Self::from_raw(ptr) }.wake_impl();
57 }
58
59 unsafe fn drop(_: *const ()) {
60 }
62}
63
64struct WakerArray<const N: usize>([Option<Waker>; N]);
65
66impl<const N: usize> Wake for WakerArray<N> {
67 fn wake(self: Arc<Self>) {
68 self.wake_by_ref();
69 }
70
71 fn wake_by_ref(self: &Arc<Self>) {
72 for waker in self.0.iter().flatten() {
73 waker.wake_by_ref();
74 }
75 }
76}