1#![no_std]
4#![deny(missing_docs)]
5
6extern crate alloc;
7
8use alloc::{boxed::Box, sync::Arc, vec::Vec};
9use core::{marker::PhantomData, task::Waker};
10
11use bitflags::bitflags;
12use linux_raw_sys::general::*;
13
14bitflags! {
15 #[derive(Debug, Clone, Copy, Eq, PartialEq)]
17 pub struct IoEvents: u32 {
18 const IN = POLLIN;
20 const PRI = POLLPRI;
22 const OUT = POLLOUT;
24 const ERR = POLLERR;
26 const HUP = POLLHUP;
28 const NVAL = POLLNVAL;
30 const RDNORM = POLLRDNORM;
32 const RDBAND = POLLRDBAND;
34 const WRNORM = POLLWRNORM;
36 const WRBAND = POLLWRBAND;
38 const MSG = POLLMSG;
40 const REMOVE = POLLREMOVE;
42 const RDHUP = POLLRDHUP;
44 const ALWAYS_POLL = Self::ERR.bits() | Self::HUP.bits();
46 }
47}
48
49pub enum SharedObserver {}
51
52pub enum ExclusiveConsumer {}
54
55#[derive(Clone, Copy, Debug, Eq, PartialEq)]
57pub enum RegistrationMode {
58 Shared,
60 Exclusive,
62}
63
64pub trait PollRegistration: Send {
66 fn was_notified(&self) -> bool;
71}
72
73pub trait PollSource: Send + Sync {
75 unsafe fn register(
85 &self,
86 waker: &Waker,
87 interests: IoEvents,
88 mode: RegistrationMode,
89 ) -> Option<Box<dyn PollRegistration>>;
90}
91
92impl<T: PollSource + ?Sized> PollSource for Arc<T> {
93 unsafe fn register(
94 &self,
95 waker: &Waker,
96 interests: IoEvents,
97 mode: RegistrationMode,
98 ) -> Option<Box<dyn PollRegistration>> {
99 unsafe { self.as_ref().register(waker, interests, mode) }
100 }
101}
102
103struct OwnedRegistration {
104 lease: Box<dyn PollRegistration>,
105 mode: RegistrationMode,
106}
107
108#[must_use = "dropping the registrar immediately cancels its poll registrations"]
112pub struct PollRegistrar<M> {
113 waker: Waker,
114 registrations: Vec<OwnedRegistration>,
115 mode: PhantomData<fn() -> M>,
116}
117
118impl<M> PollRegistrar<M> {
119 pub fn new(waker: &Waker) -> Self {
121 Self {
122 waker: waker.clone(),
123 registrations: Vec::new(),
124 mode: PhantomData,
125 }
126 }
127
128 pub fn reset(&mut self, waker: &Waker) {
130 self.registrations.clear();
131 self.waker.clone_from(waker);
132 }
133
134 pub fn clear(&mut self) {
136 self.registrations.clear();
137 }
138
139 pub fn is_empty(&self) -> bool {
141 self.registrations.is_empty()
142 }
143
144 unsafe fn register_mode(
145 &mut self,
146 source: &dyn PollSource,
147 interests: IoEvents,
148 mode: RegistrationMode,
149 ) {
150 if interests.is_empty() {
151 return;
152 }
153 if let Some(lease) = unsafe { source.register(&self.waker, interests, mode) } {
154 self.registrations.push(OwnedRegistration { lease, mode });
155 }
156 }
157}
158
159impl PollRegistrar<SharedObserver> {
160 pub unsafe fn register(&mut self, source: &dyn PollSource, interests: IoEvents) {
166 unsafe { self.register_mode(source, interests, RegistrationMode::Shared) };
167 }
168}
169
170impl PollRegistrar<ExclusiveConsumer> {
171 pub fn was_exclusively_notified(&self) -> bool {
177 self.registrations.iter().any(|registration| {
178 registration.mode == RegistrationMode::Exclusive && registration.lease.was_notified()
179 })
180 }
181
182 pub unsafe fn register_exclusive(&mut self, source: &dyn PollSource, interests: IoEvents) {
188 unsafe { self.register_mode(source, interests, RegistrationMode::Exclusive) };
189 }
190
191 pub unsafe fn register_shared(&mut self, source: &dyn PollSource, interests: IoEvents) {
197 unsafe { self.register_mode(source, interests, RegistrationMode::Shared) };
198 }
199}
200
201pub trait SharedRegistrationSink {
203 fn waker(&self) -> &Waker;
205
206 unsafe fn register_shared(&mut self, source: &dyn PollSource, interests: IoEvents);
212}
213
214pub trait ExclusiveRegistrationSink {
216 fn waker(&self) -> &Waker;
218
219 unsafe fn register_exclusive(&mut self, source: &dyn PollSource, interests: IoEvents);
225
226 fn as_shared(&mut self) -> &mut dyn SharedRegistrationSink;
228}
229
230impl SharedRegistrationSink for PollRegistrar<SharedObserver> {
231 fn waker(&self) -> &Waker {
232 &self.waker
233 }
234
235 unsafe fn register_shared(&mut self, source: &dyn PollSource, interests: IoEvents) {
236 unsafe { self.register(source, interests) };
237 }
238}
239
240impl SharedRegistrationSink for PollRegistrar<ExclusiveConsumer> {
241 fn waker(&self) -> &Waker {
242 &self.waker
243 }
244
245 unsafe fn register_shared(&mut self, source: &dyn PollSource, interests: IoEvents) {
246 unsafe { self.register_shared(source, interests) };
247 }
248}
249
250impl ExclusiveRegistrationSink for PollRegistrar<ExclusiveConsumer> {
251 fn waker(&self) -> &Waker {
252 &self.waker
253 }
254
255 unsafe fn register_exclusive(&mut self, source: &dyn PollSource, interests: IoEvents) {
256 unsafe { self.register_exclusive(source, interests) };
257 }
258
259 fn as_shared(&mut self) -> &mut dyn SharedRegistrationSink {
260 self
261 }
262}
263
264pub trait Pollable {
266 fn poll(&self) -> IoEvents;
268
269 unsafe fn register_shared(&self, sink: &mut dyn SharedRegistrationSink, events: IoEvents);
275
276 unsafe fn register_exclusive(
285 &self,
286 sink: &mut dyn ExclusiveRegistrationSink,
287 events: IoEvents,
288 ) {
289 unsafe { self.register_shared(sink.as_shared(), events) };
290 }
291}