1#![cfg_attr(nightly_tls_active, feature(thread_local))]
30#![deny(missing_docs)]
31
32pub mod fs;
33#[cfg(any(unix, windows))]
34pub mod instance;
35pub mod net;
36pub mod reactor;
37pub mod thread;
38pub mod timer;
39
40mod frame;
41
42#[cfg(unix)]
43pub mod unix;
44
45#[cfg(windows)]
46pub mod windows;
47
48#[cfg(target_arch = "wasm32")]
49pub mod wasm;
50
51#[cfg(any(target_arch = "wasm32", test))]
52#[path = "wasm/drop_validation.rs"]
53mod drop_validation;
54
55#[cfg(any(target_arch = "wasm32", test))]
56#[path = "wasm/file_policy.rs"]
57mod file_policy;
58
59#[cfg(any(target_arch = "wasm32", test))]
60#[path = "wasm/text_validation.rs"]
61mod text_validation;
62
63#[cfg(any(target_arch = "wasm32", test))]
64#[path = "wasm/text_model.rs"]
65mod text_model;
66
67#[cfg(any(target_arch = "wasm32", test))]
68#[path = "wasm/canvas_validation.rs"]
69mod canvas_validation;
70
71#[cfg(any(target_arch = "wasm32", test))]
72#[path = "wasm/gpu_device_loss.rs"]
73mod gpu_device_loss;
74
75#[cfg(any(target_arch = "wasm32", test))]
76#[path = "wasm/content_box.rs"]
77mod content_box;
78
79#[cfg(any(target_arch = "wasm32", test))]
80#[path = "wasm/history_path.rs"]
81mod history_path;
82#[cfg(any(target_arch = "wasm32", test))]
83#[path = "wasm/key_validation.rs"]
84mod key_validation;
85
86#[cfg(any(target_arch = "wasm32", test))]
87mod local_task;
88
89#[cfg(any(target_arch = "wasm32", test))]
90#[path = "websocket_state.rs"]
91mod websocket_state;
92
93use std::io;
94
95macro_rules! reactor_trait_items {
96 () => {
97 fn register_fd(&self, fd: RawFd, interest: Interest) -> io::Result<()>;
99
100 fn unregister_fd(&self, fd: RawFd) -> io::Result<()>;
102
103 fn poll_events(&self, timeout: Option<std::time::Duration>) -> io::Result<Vec<Event>>;
105
106 fn wake(&self) -> io::Result<()>;
108 };
109}
110
111#[cfg(not(target_arch = "wasm32"))]
118pub trait Reactor: Send + Sync + 'static {
119 reactor_trait_items!();
120}
121
122#[cfg(target_arch = "wasm32")]
124pub trait Reactor: 'static {
125 reactor_trait_items!();
126}
127
128#[cfg(unix)]
130pub type RawFd = std::os::unix::io::RawFd;
131
132#[cfg(windows)]
134pub type RawFd = std::os::windows::io::RawHandle;
135
136#[cfg(target_arch = "wasm32")]
138pub type RawFd = u32;
139
140#[cfg(not(any(unix, windows, target_arch = "wasm32")))]
142pub type RawFd = usize;
143
144#[cfg(target_os = "linux")]
146pub type PlatformReactor = unix::epoll::EpollReactor;
147
148#[cfg(any(
150 target_os = "macos",
151 target_os = "freebsd",
152 target_os = "openbsd",
153 target_os = "netbsd"
154))]
155pub type PlatformReactor = unix::kqueue::KqueueReactor;
156
157#[cfg(windows)]
159pub type PlatformReactor = windows::poll::WsaPollReactor;
160
161#[cfg(target_arch = "wasm32")]
163pub type PlatformReactor = wasm::WebReactor;
164
165#[cfg(not(any(
168 target_os = "linux",
169 target_os = "macos",
170 target_os = "freebsd",
171 target_os = "openbsd",
172 target_os = "netbsd",
173 windows,
174 target_arch = "wasm32"
175)))]
176pub struct PlatformReactor;
177
178#[derive(Debug, Clone, Copy)]
180pub struct Interest {
181 pub readable: bool,
183 pub writable: bool,
185 pub error: bool,
187}
188
189impl Interest {
190 pub const READABLE: Self = Self {
192 readable: true,
193 writable: false,
194 error: true,
195 };
196 pub const WRITABLE: Self = Self {
198 readable: false,
199 writable: true,
200 error: true,
201 };
202 pub const READ_WRITE: Self = Self {
204 readable: true,
205 writable: true,
206 error: true,
207 };
208}
209
210#[derive(Debug, Clone)]
212pub struct Event {
213 pub fd: RawFd,
215 pub readable: bool,
217 pub writable: bool,
219 pub error: bool,
221 pub hangup: bool,
223}
224
225#[cfg(not(any(
226 target_os = "linux",
227 target_os = "macos",
228 target_os = "freebsd",
229 target_os = "openbsd",
230 target_os = "netbsd",
231 windows,
232 target_arch = "wasm32"
233)))]
234impl Reactor for PlatformReactor {
235 fn register_fd(&self, _fd: RawFd, _interest: Interest) -> io::Result<()> {
236 Err(unsupported_reactor_error())
237 }
238
239 fn unregister_fd(&self, _fd: RawFd) -> io::Result<()> {
240 Err(unsupported_reactor_error())
241 }
242
243 fn poll_events(&self, _timeout: Option<std::time::Duration>) -> io::Result<Vec<Event>> {
244 Err(unsupported_reactor_error())
245 }
246
247 fn wake(&self) -> io::Result<()> {
248 Err(unsupported_reactor_error())
249 }
250}
251
252#[cfg(not(any(
253 target_os = "linux",
254 target_os = "macos",
255 target_os = "freebsd",
256 target_os = "openbsd",
257 target_os = "netbsd",
258 windows,
259 target_arch = "wasm32"
260)))]
261fn unsupported_reactor_error() -> io::Error {
262 io::Error::new(
263 io::ErrorKind::Unsupported,
264 "Platform not supported for native async I/O",
265 )
266}
267
268pub fn create_reactor() -> io::Result<PlatformReactor> {
270 #[cfg(target_os = "linux")]
271 return unix::epoll::EpollReactor::new();
272
273 #[cfg(any(
274 target_os = "macos",
275 target_os = "freebsd",
276 target_os = "openbsd",
277 target_os = "netbsd"
278 ))]
279 return unix::kqueue::KqueueReactor::new();
280
281 #[cfg(windows)]
282 return windows::poll::WsaPollReactor::new();
283
284 #[cfg(target_arch = "wasm32")]
285 return wasm::WebReactor::new();
286
287 #[cfg(not(any(
288 target_os = "linux",
289 target_os = "macos",
290 target_os = "freebsd",
291 target_os = "openbsd",
292 target_os = "netbsd",
293 windows,
294 target_arch = "wasm32"
295 )))]
296 return Err(io::Error::new(
297 io::ErrorKind::Unsupported,
298 "Platform not supported for native async I/O",
299 ));
300}
301
302#[cfg(test)]
303mod tests {
304 use super::*;
305
306 #[test]
307 fn test_interest_flags() {
308 let read_only = Interest::READABLE;
309 assert!(read_only.readable);
310 assert!(!read_only.writable);
311 assert!(read_only.error);
312
313 let write_only = Interest::WRITABLE;
314 assert!(!write_only.readable);
315 assert!(write_only.writable);
316 assert!(write_only.error);
317
318 let read_write = Interest::READ_WRITE;
319 assert!(read_write.readable);
320 assert!(read_write.writable);
321 assert!(read_write.error);
322 }
323}