compio_driver/fusion/
op.rs

1use std::ffi::CString;
2
3use compio_buf::{IntoInner, IoBuf, IoBufMut, IoVectoredBuf, IoVectoredBufMut};
4use socket2::SockAddr;
5
6use super::*;
7use crate::SharedFd;
8pub use crate::unix::op::*;
9
10macro_rules! op {
11    (<$($ty:ident: $trait:ident),* $(,)?> $name:ident( $($arg:ident: $arg_t:ty),* $(,)? )) => {
12        ::paste::paste!{
13            enum [< $name Inner >] <$($ty: $trait),*> {
14                Poll(poll::$name<$($ty),*>),
15                IoUring(iour::$name<$($ty),*>),
16            }
17
18            impl<$($ty: $trait),*> [< $name Inner >]<$($ty),*> {
19                fn poll(&mut self) -> &mut poll::$name<$($ty),*> {
20                    debug_assert!(DriverType::current() == DriverType::Poll);
21
22                    match self {
23                        Self::Poll(ref mut op) => op,
24                        Self::IoUring(_) => unreachable!("Current driver is not `io-uring`"),
25                    }
26                }
27
28                fn iour(&mut self) -> &mut iour::$name<$($ty),*> {
29                    debug_assert!(DriverType::current() == DriverType::IoUring);
30
31                    match self {
32                        Self::IoUring(ref mut op) => op,
33                        Self::Poll(_) => unreachable!("Current driver is not `polling`"),
34                    }
35                }
36            }
37
38            #[doc = concat!("A fused `", stringify!($name), "` operation")]
39            pub struct $name <$($ty: $trait),*> {
40                inner: [< $name Inner >] <$($ty),*>
41            }
42
43            impl<$($ty: $trait),*> IntoInner for $name <$($ty),*> {
44                type Inner = <poll::$name<$($ty),*> as IntoInner>::Inner;
45
46                fn into_inner(self) -> Self::Inner {
47                    match self.inner {
48                        [< $name Inner >]::Poll(op) => op.into_inner(),
49                        [< $name Inner >]::IoUring(op) => op.into_inner(),
50                    }
51                }
52            }
53
54            impl<$($ty: $trait),*> $name <$($ty),*> {
55                #[doc = concat!("Create a new `", stringify!($name), "`.")]
56                pub fn new($($arg: $arg_t),*) -> Self {
57                    match DriverType::current() {
58                        DriverType::Poll => Self {
59                            inner: [< $name Inner >]::Poll(poll::$name::new($($arg),*)),
60                        },
61                        DriverType::IoUring => Self {
62                            inner: [< $name Inner >]::IoUring(iour::$name::new($($arg),*)),
63                        },
64                        _ => unreachable!("Fuse driver will only be enabled on linux"),
65                    }
66                }
67            }
68        }
69
70        impl<$($ty: $trait),*> poll::OpCode for $name<$($ty),*> {
71            fn pre_submit(self: std::pin::Pin<&mut Self>) -> std::io::Result<crate::Decision> {
72                unsafe { self.map_unchecked_mut(|x| x.inner.poll() ) }.pre_submit()
73            }
74
75            fn op_type(self: std::pin::Pin<&mut Self>) -> Option<OpType> {
76                unsafe { self.map_unchecked_mut(|x| x.inner.poll() ) }.op_type()
77            }
78
79            fn operate(
80                self: std::pin::Pin<&mut Self>,
81            ) -> std::task::Poll<std::io::Result<usize>> {
82                unsafe { self.map_unchecked_mut(|x| x.inner.poll() ) }.operate()
83            }
84        }
85
86        impl<$($ty: $trait),*> iour::OpCode for $name<$($ty),*> {
87            fn create_entry(self: std::pin::Pin<&mut Self>) -> OpEntry {
88                unsafe { self.map_unchecked_mut(|x| x.inner.iour() ) }.create_entry()
89            }
90        }
91    };
92}
93
94#[rustfmt::skip]
95mod iour { pub use crate::sys::iour::{op::*, OpCode}; }
96#[rustfmt::skip]
97mod poll { pub use crate::sys::poll::{op::*, OpCode}; }
98
99op!(<T: IoBufMut, S: AsRawFd> RecvFrom(fd: SharedFd<S>, buffer: T));
100op!(<T: IoBuf, S: AsRawFd> SendTo(fd: SharedFd<S>, buffer: T, addr: SockAddr));
101op!(<T: IoVectoredBufMut, S: AsRawFd> RecvFromVectored(fd: SharedFd<S>, buffer: T));
102op!(<T: IoVectoredBuf, S: AsRawFd> SendToVectored(fd: SharedFd<S>, buffer: T, addr: SockAddr));
103op!(<S: AsRawFd> FileStat(fd: SharedFd<S>));
104op!(<> PathStat(path: CString, follow_symlink: bool));