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 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 pub fn unsubscribe(&self, fd: usize) -> Result<()> {
28 self.subscribe(fd, 0, EventFlags::empty())
30 }
31 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 }
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 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 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 fn from_user_data(user_data: usize) -> Self {
106 user_data
107 }
108}
109#[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 _marker: PhantomData<*mut U>,
132}
133
134impl<U: UserData> EventQueue<U> {
135 #[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 fn next(&mut self) -> Option<Self::Item> {
171 Some(self.next_event())
172 }
173}