1use std::{fmt, io, pin::Pin};
3
4use crate::rt::Runtime;
5
6pub type BlockFuture = Pin<Box<dyn Future<Output = ()> + 'static>>;
7
8#[derive(Copy, Clone, Debug, PartialEq, Eq)]
9pub enum DriverType {
10 Poll,
11 IoUring,
12}
13
14impl DriverType {
15 pub const fn name(&self) -> &'static str {
16 match self {
17 DriverType::Poll => "polling",
18 DriverType::IoUring => "io-uring",
19 }
20 }
21
22 pub const fn is_polling(&self) -> bool {
23 matches!(self, &DriverType::Poll)
24 }
25}
26
27pub trait Runner: Send + Sync + 'static {
28 fn block_on(&self, fut: BlockFuture);
29}
30
31pub trait Driver: 'static {
32 fn handle(&self) -> Box<dyn Notify>;
33
34 fn run(&self, rt: &Runtime) -> io::Result<()>;
35
36 fn clear(&self);
37}
38
39pub enum PollResult {
40 Ready,
41 Pending,
42 PollAgain,
43}
44
45pub trait Notify: Send + Sync + fmt::Debug + 'static {
46 fn notify(&self) -> io::Result<()>;
47}
48
49#[cfg(windows)]
50#[macro_export]
51macro_rules! syscall {
52 (BOOL, $e:expr) => {
53 $crate::syscall!($e, == 0)
54 };
55 (SOCKET, $e:expr) => {
56 $crate::syscall!($e, != 0)
57 };
58 (HANDLE, $e:expr) => {
59 $crate::syscall!($e, == ::windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE)
60 };
61 ($e:expr, $op: tt $rhs: expr) => {{
62 #[allow(unused_unsafe)]
63 let res = unsafe { $e };
64 if res $op $rhs {
65 Err(::std::io::Error::last_os_error())
66 } else {
67 Ok(res)
68 }
69 }};
70}
71
72#[cfg(unix)]
74#[macro_export]
75macro_rules! syscall {
76 (break $e:expr) => {
77 loop {
78 match $crate::syscall!($e) {
79 Ok(fd) => break ::std::task::Poll::Ready(Ok(fd as usize)),
80 Err(e) if e.kind() == ::std::io::ErrorKind::WouldBlock || e.raw_os_error() == Some(::libc::EINPROGRESS)
81 => break ::std::task::Poll::Pending,
82 Err(e) if e.kind() == ::std::io::ErrorKind::Interrupted => {},
83 Err(e) => break ::std::task::Poll::Ready(Err(e)),
84 }
85 }
86 };
87 ($e:expr, $f:ident($fd:expr)) => {
88 match $crate::syscall!(break $e) {
89 ::std::task::Poll::Pending => Ok($crate::sys::Decision::$f($fd)),
90 ::std::task::Poll::Ready(Ok(res)) => Ok($crate::sys::Decision::Completed(res)),
91 ::std::task::Poll::Ready(Err(e)) => Err(e),
92 }
93 };
94 ($e:expr) => {{
95 #[allow(unused_unsafe)]
96 let res = unsafe { $e };
97 if res == -1 {
98 Err(::std::io::Error::last_os_error())
99 } else {
100 Ok(res)
101 }
102 }};
103}