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
39#[derive(Copy, Clone, Debug, PartialEq, Eq)]
40pub enum PollResult {
41 Ready,
42 Pending,
43 PollAgain,
44}
45
46pub trait Notify: Send + Sync + fmt::Debug + 'static {
47 fn notify(&self) -> io::Result<()>;
48}
49
50#[cfg(windows)]
51#[macro_export]
52macro_rules! syscall {
53 (BOOL, $e:expr) => {
54 $crate::syscall!($e, == 0)
55 };
56 (SOCKET, $e:expr) => {
57 $crate::syscall!($e, != 0)
58 };
59 (HANDLE, $e:expr) => {
60 $crate::syscall!($e, == ::windows_sys::Win32::Foundation::INVALID_HANDLE_VALUE)
61 };
62 ($e:expr, $op: tt $rhs: expr) => {{
63 #[allow(unused_unsafe)]
64 let res = unsafe { $e };
65 if res $op $rhs {
66 Err(::std::io::Error::last_os_error())
67 } else {
68 Ok(res)
69 }
70 }};
71}
72
73#[cfg(unix)]
75#[macro_export]
76macro_rules! syscall {
77 (break $e:expr) => {
78 loop {
79 match $crate::syscall!($e) {
80 Ok(fd) => break ::std::task::Poll::Ready(Ok(fd as usize)),
81 Err(e) if e.kind() == ::std::io::ErrorKind::WouldBlock || e.raw_os_error() == Some(::libc::EINPROGRESS)
82 => break ::std::task::Poll::Pending,
83 Err(e) if e.kind() == ::std::io::ErrorKind::Interrupted => {},
84 Err(e) => break ::std::task::Poll::Ready(Err(e)),
85 }
86 }
87 };
88 ($e:expr, $f:ident($fd:expr)) => {
89 match $crate::syscall!(break $e) {
90 ::std::task::Poll::Pending => Ok($crate::sys::Decision::$f($fd)),
91 ::std::task::Poll::Ready(Ok(res)) => Ok($crate::sys::Decision::Completed(res)),
92 ::std::task::Poll::Ready(Err(e)) => Err(e),
93 }
94 };
95 ($e:expr) => {{
96 #[allow(unused_unsafe)]
97 let res = unsafe { $e };
98 if res == -1 {
99 Err(::std::io::Error::last_os_error())
100 } else {
101 Ok(res)
102 }
103 }};
104}