event/
wrappers.rs

1use core::marker::PhantomData;
2use core::mem::MaybeUninit;
3
4use libredox::error::{Error, Result};
5
6use crate::raw;
7pub use crate::raw::EventFlags;
8
9pub struct RawEventQueue {
10    inner: usize,
11}
12pub type RawEvent = raw::RawEventV1;
13impl RawEventQueue {
14    pub fn new() -> Result<Self> {
15        Ok(Self {
16            inner: Error::demux(unsafe { raw::redox_event_queue_create_v1(0) })?,
17        })
18    }
19    /// Subscribe to events produced by `fd`
20    pub fn subscribe(&self, fd: usize, user_data: usize, flags: EventFlags) -> Result<()> {
21        let _ = Error::demux(unsafe {
22            raw::redox_event_queue_ctl_v1(self.inner, fd, flags.bits(), user_data)
23        })?;
24        Ok(())
25    }
26    /// Unsubscribe from events produced by `fd`
27    pub fn unsubscribe(&self, fd: usize) -> Result<()> {
28        // TODO: Will user_data be needed?
29        self.subscribe(fd, 0, EventFlags::empty())
30    }
31    // TODO: next_events
32    pub fn next_event(&self) -> Result<RawEvent> {
33        let mut event = MaybeUninit::uninit();
34
35        unsafe {
36            let res = Error::demux(raw::redox_event_queue_get_events_v1(
37                self.inner,
38                event.as_mut_ptr(),
39                1,
40                0,
41                core::ptr::null(),
42                core::ptr::null(),
43            ))?;
44            assert_eq!(res, 1, "EOF is not yet well defined for event queues");
45            Ok(event.assume_init())
46        }
47    }
48    pub fn iter(&self) -> impl Iterator<Item = Result<RawEvent>> + '_ {
49        core::iter::from_fn(|| Some(self.next_event()))
50    }
51    // TODO: "next_event_nonblock"?
52}
53impl Drop for RawEventQueue {
54    fn drop(&mut self) {
55        unsafe {
56            let _ = Error::demux(raw::redox_event_queue_destroy_v1(self.inner));
57        }
58    }
59}
60impl Iterator for RawEventQueue {
61    type Item = Result<RawEvent>;
62
63    // TODO: next_chunk
64    fn next(&mut self) -> Option<Self::Item> {
65        Some(self.next_event())
66    }
67}
68
69#[macro_export]
70macro_rules! user_data {
71    {
72        $vis:vis enum $name:ident {
73            $($variant:ident),*$(,)?
74        }
75    } => {
76        #[derive(Clone, Copy, Debug, Eq, Hash, Ord, PartialEq, PartialOrd)]
77        #[repr(usize)]
78        $vis enum $name {
79            $($variant),*
80        }
81
82        impl $crate::UserData for $name {
83            fn into_user_data(self) -> usize {
84                self as usize
85            }
86            fn from_user_data(raw: usize) -> Self {
87                assert!(raw < [$(Self::$variant),*].len());
88                //assert!(raw < core::mem::variant_count::<$name>());
89
90                unsafe { ::core::mem::transmute(raw) }
91            }
92        }
93    };
94}
95
96pub trait UserData: Clone + Copy {
97    fn into_user_data(self) -> usize;
98    fn from_user_data(user_data: usize) -> Self;
99}
100impl UserData for usize {
101    fn into_user_data(self) -> usize {
102        self
103    }
104    // TODO: make unsafe fn
105    fn from_user_data(user_data: usize) -> Self {
106        user_data
107    }
108}
109/*
110unsafe impl<'a, T> UserData for &'a T {
111    fn into_user_data(self) -> usize {
112        self as *const T as usize
113    }
114    unsafe fn from_user_data(user_data: usize) -> Self {
115        &*(user_data as *const T)
116    }
117}
118*/
119
120#[non_exhaustive]
121pub struct Event<U: UserData> {
122    pub user_data: U,
123    pub flags: EventFlags,
124    pub fd: usize,
125}
126
127pub struct EventQueue<U: UserData> {
128    inner: RawEventQueue,
129
130    // We'll be casting user_data to and from U, so ensure it's invariant.
131    _marker: PhantomData<*mut U>,
132}
133
134impl<U: UserData> EventQueue<U> {
135    /// Create a new event queue
136    #[inline]
137    pub fn new() -> Result<Self> {
138        Ok(EventQueue {
139            inner: RawEventQueue::new()?,
140            _marker: PhantomData,
141        })
142    }
143    #[inline]
144    pub fn subscribe(&self, fd: usize, data: U, flags: EventFlags) -> Result<()> {
145        self.inner.subscribe(fd, data.into_user_data(), flags)
146    }
147    #[inline]
148    pub fn unsubscribe(&self, fd: usize) -> Result<()> {
149        self.inner.unsubscribe(fd)
150    }
151    #[inline]
152    pub fn raw(&self) -> &RawEventQueue {
153        &self.inner
154    }
155    pub fn next_event(&self) -> Result<Event<U>> {
156        self.inner.next_event().map(|raw| Event {
157            user_data: U::from_user_data(raw.user_data),
158            fd: raw.fd,
159            flags: EventFlags::from_bits_retain(raw.flags),
160        })
161    }
162    pub fn iter(&self) -> impl Iterator<Item = Result<Event<U>>> + '_ {
163        core::iter::from_fn(|| Some(self.next_event()))
164    }
165}
166impl<U: UserData> Iterator for EventQueue<U> {
167    type Item = Result<Event<U>>;
168
169    // TODO: next_chunk
170    fn next(&mut self) -> Option<Self::Item> {
171        Some(self.next_event())
172    }
173}