compio_driver/sys/fusion/
mod.rs1pub(crate) mod op;
2
3#[cfg_attr(all(doc, docsrs), doc(cfg(all())))]
4pub use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd};
5use std::{
6 io,
7 task::{Poll, Waker},
8 time::Duration,
9};
10
11use compio_buf::BufResult;
12use compio_log::warn;
13pub use iour::{IourOpCode, OpEntry};
14pub use poll::{Decision, OpType, PollOpCode};
15
16pub(crate) use super::iour::{is_op_supported, take_buffer};
17use super::{iour, poll};
18pub use crate::driver_type::DriverType; use crate::{BufferPool, ProactorBuilder, key::ErasedKey};
20
21mod extra;
22pub(in crate::sys) use extra::Extra;
23
24pub trait OpCode: PollOpCode + IourOpCode {}
28
29impl<T: PollOpCode + IourOpCode + ?Sized> OpCode for T {}
30
31#[allow(clippy::large_enum_variant)]
32enum FuseDriver {
33 Poll(poll::Driver),
34 IoUring(iour::Driver),
35}
36
37pub(crate) struct Driver {
39 fuse: FuseDriver,
40}
41
42impl Driver {
43 pub fn new(builder: &ProactorBuilder) -> io::Result<Self> {
45 let (ty, fallback) = match &builder.driver_type {
46 Some(t) => (*t, false),
47 None => (DriverType::suggest(builder.op_flags), true),
48 };
49 match ty {
50 DriverType::Poll => Ok(Self {
51 fuse: FuseDriver::Poll(poll::Driver::new(builder)?),
52 }),
53 DriverType::IoUring => match iour::Driver::new(builder) {
54 Ok(driver) => Ok(Self {
55 fuse: FuseDriver::IoUring(driver),
56 }),
57 Err(_e) if fallback => {
59 warn!("Fail to create io-uring driver: {_e:?}, fallback to polling driver.");
60 Ok(Self {
61 fuse: FuseDriver::Poll(poll::Driver::new(builder)?),
62 })
63 }
64 Err(e) => Err(e),
65 },
66 _ => unreachable!("Fuse driver will only be enabled on linux"),
67 }
68 }
69
70 #[allow(dead_code)]
71 pub fn as_iour(&self) -> Option<&iour::Driver> {
72 if let FuseDriver::IoUring(driver) = &self.fuse {
73 Some(driver)
74 } else {
75 None
76 }
77 }
78
79 pub fn driver_type(&self) -> DriverType {
80 match &self.fuse {
81 FuseDriver::Poll(driver) => driver.driver_type(),
82 FuseDriver::IoUring(driver) => driver.driver_type(),
83 }
84 }
85
86 pub(in crate::sys) fn default_extra(&self) -> Extra {
87 match &self.fuse {
88 FuseDriver::Poll(driver) => Extra::Poll(driver.default_extra()),
89 FuseDriver::IoUring(driver) => Extra::IoUring(driver.default_extra()),
90 }
91 }
92
93 pub fn attach(&mut self, fd: RawFd) -> io::Result<()> {
94 match &mut self.fuse {
95 FuseDriver::Poll(driver) => driver.attach(fd),
96 FuseDriver::IoUring(driver) => driver.attach(fd),
97 }
98 }
99
100 pub fn cancel(&mut self, key: ErasedKey) {
101 match &mut self.fuse {
102 FuseDriver::Poll(driver) => driver.cancel(key),
103 FuseDriver::IoUring(driver) => driver.cancel(key),
104 }
105 }
106
107 pub fn push(&mut self, op: ErasedKey) -> Poll<io::Result<usize>> {
108 match &mut self.fuse {
109 FuseDriver::Poll(driver) => driver.push(op),
110 FuseDriver::IoUring(driver) => driver.push(op),
111 }
112 }
113
114 pub fn poll(&mut self, timeout: Option<Duration>) -> io::Result<()> {
115 match &mut self.fuse {
116 FuseDriver::Poll(driver) => driver.poll(timeout),
117 FuseDriver::IoUring(driver) => driver.poll(timeout),
118 }
119 }
120
121 pub fn waker(&self) -> Waker {
122 match &self.fuse {
123 FuseDriver::Poll(driver) => driver.waker(),
124 FuseDriver::IoUring(driver) => driver.waker(),
125 }
126 }
127
128 pub fn create_buffer_pool(
129 &mut self,
130 buffer_len: u16,
131 buffer_size: usize,
132 ) -> io::Result<BufferPool> {
133 match &mut self.fuse {
134 FuseDriver::IoUring(driver) => Ok(driver.create_buffer_pool(buffer_len, buffer_size)?),
135 FuseDriver::Poll(driver) => Ok(driver.create_buffer_pool(buffer_len, buffer_size)?),
136 }
137 }
138
139 pub unsafe fn release_buffer_pool(&mut self, buffer_pool: BufferPool) -> io::Result<()> {
143 unsafe {
144 match &mut self.fuse {
145 FuseDriver::Poll(driver) => driver.release_buffer_pool(buffer_pool),
146 FuseDriver::IoUring(driver) => driver.release_buffer_pool(buffer_pool),
147 }
148 }
149 }
150
151 pub fn pop_multishot(
152 &mut self,
153 key: &ErasedKey,
154 ) -> Option<BufResult<usize, crate::sys::Extra>> {
155 match &mut self.fuse {
156 FuseDriver::Poll(driver) => driver.pop_multishot(key),
157 FuseDriver::IoUring(driver) => driver.pop_multishot(key),
158 }
159 }
160}
161
162impl AsRawFd for Driver {
163 fn as_raw_fd(&self) -> RawFd {
164 match &self.fuse {
165 FuseDriver::Poll(driver) => driver.as_raw_fd(),
166 FuseDriver::IoUring(driver) => driver.as_raw_fd(),
167 }
168 }
169}