1#![cfg_attr(any(windows, target_os = "linux"), expect(unsafe_code))]
8
9#[cfg(unix)]
10use crate::fd::FdReadyDriver;
11#[cfg(unix)]
12use crate::fd::PollFdReady;
13#[cfg(target_os = "linux")]
14use crate::io_uring::IoUringDriver;
15use crate::socket::PollSocketReady;
16use crate::socket::SocketReadyDriver;
17#[cfg(windows)]
18use crate::sys::overlapped::IoOverlapped;
19#[cfg(windows)]
20use crate::sys::overlapped::OverlappedIoDriver;
21use crate::task::Spawn;
22use crate::timer::PollTimer;
23use crate::timer::TimerDriver;
24use crate::wait::PollWait;
25use crate::wait::WaitDriver;
26use smallbox::SmallBox;
27use smallbox::space::S4;
28use std::io;
29#[cfg(unix)]
30use std::os::unix::prelude::*;
31#[cfg(windows)]
32use std::os::windows::prelude::*;
33use std::sync::Arc;
34
35pub type PollImpl<T> = SmallBox<T, S4>;
37
38pub trait Driver: 'static + Send + Sync {
40 fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer>;
42
43 #[cfg(unix)]
45 fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>>;
46
47 #[cfg(windows)]
49 fn new_dyn_socket_ready(&self, socket: RawSocket) -> io::Result<PollImpl<dyn PollSocketReady>>;
50
51 #[cfg(unix)]
53 fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>>;
54
55 #[cfg(windows)]
57 fn new_dyn_wait(&self, handle: RawHandle) -> io::Result<PollImpl<dyn PollWait>>;
58
59 #[cfg(unix)]
65 fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>>;
66
67 #[cfg(windows)]
73 unsafe fn new_dyn_overlapped_file(
74 &self,
75 handle: RawHandle,
76 ) -> io::Result<PollImpl<dyn IoOverlapped>>;
77
78 #[cfg(target_os = "linux")]
80 fn io_uring_probe(&self, opcode: u8) -> bool;
81
82 #[cfg(target_os = "linux")]
127 unsafe fn io_uring_submit(
128 &self,
129 sqe: crate::io_uring::Entry,
130 ) -> std::pin::Pin<Box<dyn Future<Output = io::Result<i32>> + Send + '_>>;
131}
132
133#[cfg(all(unix, not(target_os = "linux")))]
134impl<T> Driver for T
135where
136 T: 'static + Send + Sync + FdReadyDriver + TimerDriver + SocketReadyDriver + WaitDriver,
137{
138 fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
139 smallbox::smallbox!(self.new_timer())
140 }
141
142 fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>> {
143 Ok(smallbox::smallbox!(self.new_fd_ready(fd)?))
144 }
145
146 fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>> {
147 Ok(smallbox::smallbox!(self.new_socket_ready(socket)?))
148 }
149
150 fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>> {
151 Ok(smallbox::smallbox!(self.new_wait(fd, read_size)?))
152 }
153}
154
155#[cfg(target_os = "linux")]
156impl<T> Driver for T
157where
158 T: 'static
159 + Send
160 + Sync
161 + FdReadyDriver
162 + TimerDriver
163 + SocketReadyDriver
164 + WaitDriver
165 + IoUringDriver,
166{
167 fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
168 smallbox::smallbox!(self.new_timer())
169 }
170
171 fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>> {
172 Ok(smallbox::smallbox!(self.new_fd_ready(fd)?))
173 }
174
175 fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>> {
176 Ok(smallbox::smallbox!(self.new_socket_ready(socket)?))
177 }
178
179 fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>> {
180 Ok(smallbox::smallbox!(self.new_wait(fd, read_size)?))
181 }
182
183 fn io_uring_probe(&self, opcode: u8) -> bool {
184 use crate::io_uring::IoUringSubmit as _;
185
186 self.io_uring_submitter()
187 .is_some_and(|submitter| submitter.probe(opcode))
188 }
189
190 unsafe fn io_uring_submit(
191 &self,
192 sqe: crate::io_uring::Entry,
193 ) -> std::pin::Pin<Box<dyn Future<Output = io::Result<i32>> + Send + '_>> {
194 use crate::io_uring::IoUringSubmit as _;
195
196 Box::pin(async move {
197 unsafe {
199 self.io_uring_submitter()
200 .ok_or(io::ErrorKind::Unsupported)?
201 .submit(sqe)
202 }
203 .await
204 })
205 }
206}
207
208#[cfg(windows)]
209impl<T> Driver for T
210where
211 T: 'static + Send + Sync + TimerDriver + SocketReadyDriver + WaitDriver + OverlappedIoDriver,
212{
213 fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
214 smallbox::smallbox!(self.new_timer())
215 }
216
217 fn new_dyn_socket_ready(&self, socket: RawSocket) -> io::Result<PollImpl<dyn PollSocketReady>> {
218 Ok(smallbox::smallbox!(self.new_socket_ready(socket)?))
219 }
220
221 fn new_dyn_wait(&self, handle: RawHandle) -> io::Result<PollImpl<dyn PollWait>> {
222 Ok(smallbox::smallbox!(self.new_wait(handle)?))
223 }
224
225 unsafe fn new_dyn_overlapped_file(
226 &self,
227 handle: RawHandle,
228 ) -> io::Result<PollImpl<dyn IoOverlapped>> {
229 Ok(smallbox::smallbox!(unsafe {
231 self.new_overlapped_file(handle)
232 }?))
233 }
234}
235
236#[cfg(unix)]
237impl Driver for Box<dyn Driver> {
238 fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
239 self.as_ref().new_dyn_timer()
240 }
241
242 fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>> {
243 self.as_ref().new_dyn_fd_ready(fd)
244 }
245
246 fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>> {
247 self.as_ref().new_dyn_socket_ready(socket)
248 }
249
250 fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>> {
251 self.as_ref().new_dyn_wait(fd, read_size)
252 }
253
254 #[cfg(target_os = "linux")]
255 fn io_uring_probe(&self, opcode: u8) -> bool {
256 self.as_ref().io_uring_probe(opcode)
257 }
258
259 #[cfg(target_os = "linux")]
260 unsafe fn io_uring_submit(
261 &self,
262 sqe: crate::io_uring::Entry,
263 ) -> std::pin::Pin<Box<dyn Future<Output = io::Result<i32>> + Send + '_>> {
264 unsafe { self.as_ref().io_uring_submit(sqe) }
266 }
267}
268
269#[cfg(windows)]
270impl Driver for Box<dyn Driver> {
271 fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
272 self.as_ref().new_dyn_timer()
273 }
274
275 fn new_dyn_socket_ready(&self, socket: RawSocket) -> io::Result<PollImpl<dyn PollSocketReady>> {
276 self.as_ref().new_dyn_socket_ready(socket)
277 }
278
279 fn new_dyn_wait(&self, handle: RawHandle) -> io::Result<PollImpl<dyn PollWait>> {
280 self.as_ref().new_dyn_wait(handle)
281 }
282
283 unsafe fn new_dyn_overlapped_file(
284 &self,
285 handle: RawHandle,
286 ) -> io::Result<PollImpl<dyn IoOverlapped>> {
287 unsafe { self.as_ref().new_dyn_overlapped_file(handle) }
289 }
290}
291
292#[cfg(unix)]
293impl Driver for Arc<dyn Driver> {
294 fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
295 self.as_ref().new_dyn_timer()
296 }
297
298 fn new_dyn_fd_ready(&self, fd: RawFd) -> io::Result<PollImpl<dyn PollFdReady>> {
299 self.as_ref().new_dyn_fd_ready(fd)
300 }
301
302 fn new_dyn_socket_ready(&self, socket: RawFd) -> io::Result<PollImpl<dyn PollSocketReady>> {
303 self.as_ref().new_dyn_socket_ready(socket)
304 }
305
306 fn new_dyn_wait(&self, fd: RawFd, read_size: usize) -> io::Result<PollImpl<dyn PollWait>> {
307 self.as_ref().new_dyn_wait(fd, read_size)
308 }
309
310 #[cfg(target_os = "linux")]
311 fn io_uring_probe(&self, opcode: u8) -> bool {
312 self.as_ref().io_uring_probe(opcode)
313 }
314
315 #[cfg(target_os = "linux")]
316 unsafe fn io_uring_submit(
317 &self,
318 sqe: crate::io_uring::Entry,
319 ) -> std::pin::Pin<Box<dyn Future<Output = io::Result<i32>> + Send + '_>> {
320 unsafe { self.as_ref().io_uring_submit(sqe) }
322 }
323}
324
325#[cfg(windows)]
326impl Driver for Arc<dyn Driver> {
327 fn new_dyn_timer(&self) -> PollImpl<dyn PollTimer> {
328 self.as_ref().new_dyn_timer()
329 }
330
331 fn new_dyn_socket_ready(&self, socket: RawSocket) -> io::Result<PollImpl<dyn PollSocketReady>> {
332 self.as_ref().new_dyn_socket_ready(socket)
333 }
334
335 fn new_dyn_wait(&self, handle: RawHandle) -> io::Result<PollImpl<dyn PollWait>> {
336 self.as_ref().new_dyn_wait(handle)
337 }
338
339 unsafe fn new_dyn_overlapped_file(
340 &self,
341 handle: RawHandle,
342 ) -> io::Result<PollImpl<dyn IoOverlapped>> {
343 unsafe { self.as_ref().new_dyn_overlapped_file(handle) }
345 }
346}
347
348pub trait SpawnDriver: Spawn + Driver {}
350
351impl<T: Spawn + Driver> SpawnDriver for T {}