Skip to main content

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