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 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 pub fn unsubscribe(&self, fd: usize) -> Result<()> {
29 self.subscribe(fd, 0, EventFlags::empty())
31 }
32 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 }
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 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 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 fn from_user_data(user_data: usize) -> Self {
107 user_data
108 }
109}
110#[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 _marker: PhantomData<*mut U>,
134}
135
136impl<U: UserData> EventQueue<U> {
137 #[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 fn next(&mut self) -> Option<Self::Item> {
173 Some(self.next_event())
174 }
175}
176
177unsafe impl<U: UserData> Send for EventQueue<U> {}
178unsafe impl<U: UserData> Sync for EventQueue<U> {}