1use super::plugin::Interface;
6use crate::{flags, hook::HookId};
7use std::{any::Any, os::fd::RawFd, pin::Pin, time::Duration};
8
9#[derive(Copy, Clone, Debug)]
10pub struct Source {
11 pub fd: RawFd,
12 pub mask: u32,
13 pub rmask: u32,
14}
15
16pub type SourceFn = dyn FnMut(&Source) + Send + 'static;
17pub type InvokeFn = dyn FnMut(bool, u32, &[u8]) -> i32 + Send + 'static;
18
19pub struct LoopImpl {
20 pub inner: Pin<Box<dyn Any>>,
21
22 pub add_source: fn(&mut LoopImpl, source: &Source, func: Box<SourceFn>) -> std::io::Result<i32>,
23 pub update_source: fn(&mut LoopImpl, source: &Source) -> std::io::Result<i32>,
24 pub remove_source: fn(&mut LoopImpl, fd: RawFd) -> std::io::Result<i32>,
25 #[allow(clippy::type_complexity)]
26 pub invoke: fn(
27 this: &LoopImpl,
28 seq: u32,
29 data: &[u8],
30 block: bool,
31 func: Box<InvokeFn>,
32 ) -> std::io::Result<i32>,
33}
34
35unsafe impl Send for LoopImpl {}
36unsafe impl Sync for LoopImpl {}
37
38impl LoopImpl {
39 pub fn add_source(&mut self, source: &Source, func: Box<SourceFn>) -> std::io::Result<i32> {
40 (self.add_source)(self, source, func)
41 }
42
43 pub fn update_source(&mut self, source: &Source) -> std::io::Result<i32> {
44 (self.update_source)(self, source)
45 }
46
47 pub fn remove_source(&mut self, fd: RawFd) -> std::io::Result<i32> {
48 (self.remove_source)(self, fd)
49 }
50
51 pub fn invoke(
52 &self,
53 seq: u32,
54 data: &[u8],
55 block: bool,
56 func: Box<InvokeFn>,
57 ) -> std::io::Result<i32> {
58 (self.invoke)(self, seq, data, block, func)
59 }
60}
61
62impl Interface for LoopImpl {
63 unsafe fn make_native(&self) -> *mut super::ffi::CInterface {
64 crate::support::ffi::r#loop::make_native(self)
65 }
66
67 unsafe fn free_native(loop_: *mut super::ffi::CInterface) {
68 crate::support::ffi::r#loop::free_native(loop_)
69 }
70}
71
72pub struct LoopControlHooks {
73 pub before: Option<Box<dyn FnMut()>>,
74 pub after: Option<Box<dyn FnMut()>>,
75}
76
77pub struct LoopControlImpl {
78 pub inner: Pin<Box<dyn Any>>,
79
80 pub get_fd: fn(&LoopControlImpl) -> u32,
81 pub add_hook: fn(&LoopControlImpl, hooks: LoopControlHooks) -> HookId,
82 pub remove_hook: fn(&LoopControlImpl, hook: HookId),
83 pub enter: fn(&LoopControlImpl),
84 pub leave: fn(&LoopControlImpl),
85 pub iterate: fn(&LoopControlImpl, timeout: Option<Duration>) -> std::io::Result<i32>,
86 pub check: fn(&LoopControlImpl) -> std::io::Result<i32>,
87 pub lock: fn(&LoopControlImpl) -> std::io::Result<i32>,
88 pub unlock: fn(&LoopControlImpl) -> std::io::Result<i32>,
89 pub get_time: fn(&LoopControlImpl, timeout: Duration) -> std::io::Result<libc::timespec>,
90 pub wait: fn(&LoopControlImpl, abstime: &libc::timespec) -> std::io::Result<i32>,
91 pub signal: fn(&LoopControlImpl, wait_for_accept: bool) -> std::io::Result<i32>,
92 pub accept: fn(&LoopControlImpl) -> std::io::Result<i32>,
93}
94
95unsafe impl Send for LoopControlImpl {}
96unsafe impl Sync for LoopControlImpl {}
97
98impl LoopControlImpl {
99 pub fn get_fd(&self) -> u32 {
100 (self.get_fd)(self)
101 }
102
103 pub fn add_hook(&self, hooks: LoopControlHooks) -> HookId {
104 (self.add_hook)(self, hooks)
105 }
106
107 pub fn remove_hook(&self, hook: HookId) {
108 (self.remove_hook)(self, hook)
109 }
110
111 pub fn enter(&self) {
112 (self.enter)(self)
113 }
114
115 pub fn leave(&self) {
116 (self.leave)(self)
117 }
118
119 pub fn iterate(&self, timeout: Option<Duration>) -> std::io::Result<i32> {
120 (self.iterate)(self, timeout)
121 }
122
123 pub fn check(&self) -> std::io::Result<i32> {
124 (self.check)(self)
125 }
126
127 pub fn lock(&self) -> std::io::Result<i32> {
128 (self.lock)(self)
129 }
130
131 pub fn unlock(&self) -> std::io::Result<i32> {
132 (self.unlock)(self)
133 }
134
135 pub fn get_time(&self, timeout: Duration) -> std::io::Result<libc::timespec> {
136 (self.get_time)(self, timeout)
137 }
138
139 pub fn wait(&self, abstime: &libc::timespec) -> std::io::Result<i32> {
140 (self.wait)(self, abstime)
141 }
142
143 pub fn signal(&self, wait_for_accept: bool) -> std::io::Result<i32> {
144 (self.signal)(self, wait_for_accept)
145 }
146
147 pub fn accept(&self) -> std::io::Result<i32> {
148 (self.accept)(self)
149 }
150}
151
152impl Interface for LoopControlImpl {
153 unsafe fn make_native(&self) -> *mut super::ffi::CInterface {
154 crate::support::ffi::r#loop::control::make_native(self)
155 }
156
157 unsafe fn free_native(loop_: *mut super::ffi::CInterface) {
158 crate::support::ffi::r#loop::control::free_native(loop_)
159 }
160}
161
162pub type SourceIoFn = dyn FnMut(RawFd, u32) + Send + 'static;
163pub type SourceIdleFn = dyn FnMut() + Send + 'static;
164pub type SourceEventFn = dyn FnMut(u64) + Send + 'static;
165pub type SourceTimerFn = dyn FnMut(u64) + Send + 'static;
166pub type SourceSignalFn = dyn FnMut(i32) + Send + 'static;
167
168pub enum LoopUtilsSourceCb {
169 Io(Box<SourceIoFn>),
170 Idle(Box<SourceIdleFn>),
171 Event(Box<SourceEventFn>),
172 Timer(Box<SourceTimerFn>),
173 Signal(Box<SourceSignalFn>),
174}
175
176pub struct LoopUtilsSource {
177 pub cb: LoopUtilsSourceCb,
178 pub mask: flags::Io,
179 pub inner: Box<dyn Any>,
180}
181
182#[allow(clippy::type_complexity)]
183pub struct LoopUtilsImpl {
184 pub inner: Pin<Box<dyn Any>>,
185
186 pub add_io: fn(
187 &LoopUtilsImpl,
188 fd: RawFd,
189 mask: flags::Io,
190 close: bool,
191 func: Box<SourceIoFn>,
192 ) -> Option<Pin<Box<LoopUtilsSource>>>,
193 pub update_io: fn(
194 &LoopUtilsImpl,
195 source: &mut Pin<Box<LoopUtilsSource>>,
196 mask: flags::Io,
197 ) -> std::io::Result<i32>,
198 pub add_idle: fn(
199 &LoopUtilsImpl,
200 enabled: bool,
201 func: Box<SourceIdleFn>,
202 ) -> Option<Pin<Box<LoopUtilsSource>>>,
203 pub enable_idle: fn(
204 &LoopUtilsImpl,
205 source: &mut Pin<Box<LoopUtilsSource>>,
206 enabled: bool,
207 ) -> std::io::Result<i32>,
208 pub add_event:
209 fn(&LoopUtilsImpl, func: Box<SourceEventFn>) -> Option<Pin<Box<LoopUtilsSource>>>,
210 pub signal_event:
211 fn(&LoopUtilsImpl, source: &mut Pin<Box<LoopUtilsSource>>) -> std::io::Result<i32>,
212 pub add_timer:
213 fn(&LoopUtilsImpl, func: Box<SourceTimerFn>) -> Option<Pin<Box<LoopUtilsSource>>>,
214 pub update_timer: fn(
215 &LoopUtilsImpl,
216 source: &mut Pin<Box<LoopUtilsSource>>,
217 value: &libc::timespec,
218 interval: Option<&libc::timespec>,
219 absolute: bool,
220 ) -> std::io::Result<i32>,
221 pub add_signal: fn(
222 &LoopUtilsImpl,
223 signal_number: i32,
224 func: Box<SourceSignalFn>,
225 ) -> Option<Pin<Box<LoopUtilsSource>>>,
226 pub destroy_source: fn(&LoopUtilsImpl, source: Pin<Box<LoopUtilsSource>>),
227}
228
229unsafe impl Send for LoopUtilsImpl {}
230unsafe impl Sync for LoopUtilsImpl {}
231
232impl LoopUtilsImpl {
233 pub fn add_io(
234 &self,
235 fd: RawFd,
236 mask: flags::Io,
237 close: bool,
238 func: Box<SourceIoFn>,
239 ) -> Option<Pin<Box<LoopUtilsSource>>> {
240 (self.add_io)(self, fd, mask, close, func)
241 }
242
243 pub fn update_io(
244 &self,
245 source: &mut Pin<Box<LoopUtilsSource>>,
246 mask: flags::Io,
247 ) -> std::io::Result<i32> {
248 (self.update_io)(self, source, mask)
249 }
250
251 pub fn add_idle(
252 &self,
253 enabled: bool,
254 func: Box<SourceIdleFn>,
255 ) -> Option<Pin<Box<LoopUtilsSource>>> {
256 (self.add_idle)(self, enabled, func)
257 }
258
259 pub fn enable_idle(
260 &self,
261 source: &mut Pin<Box<LoopUtilsSource>>,
262 enabled: bool,
263 ) -> std::io::Result<i32> {
264 (self.enable_idle)(self, source, enabled)
265 }
266
267 pub fn add_event(&self, func: Box<SourceEventFn>) -> Option<Pin<Box<LoopUtilsSource>>> {
268 (self.add_event)(self, func)
269 }
270
271 pub fn signal_event(&self, source: &mut Pin<Box<LoopUtilsSource>>) -> std::io::Result<i32> {
272 (self.signal_event)(self, source)
273 }
274
275 pub fn add_timer(&self, func: Box<SourceTimerFn>) -> Option<Pin<Box<LoopUtilsSource>>> {
276 (self.add_timer)(self, func)
277 }
278
279 pub fn update_timer(
280 &self,
281 source: &mut Pin<Box<LoopUtilsSource>>,
282 value: &libc::timespec,
283 interval: Option<&libc::timespec>,
284 absolute: bool,
285 ) -> std::io::Result<i32> {
286 (self.update_timer)(self, source, value, interval, absolute)
287 }
288
289 pub fn add_signal(
290 &self,
291 signal_number: i32,
292 func: Box<SourceSignalFn>,
293 ) -> Option<Pin<Box<LoopUtilsSource>>> {
294 (self.add_signal)(self, signal_number, func)
295 }
296
297 pub fn destroy_source(&self, source: Pin<Box<LoopUtilsSource>>) {
298 (self.destroy_source)(self, source)
299 }
300}
301
302impl Interface for LoopUtilsImpl {
303 unsafe fn make_native(&self) -> *mut super::ffi::CInterface {
304 crate::support::ffi::r#loop::utils::make_native(self)
305 }
306
307 unsafe fn free_native(loop_: *mut super::ffi::CInterface) {
308 crate::support::ffi::r#loop::utils::free_native(loop_)
309 }
310}