compio_driver/fusion/
mod.rs1#[path = "../poll/mod.rs"]
2mod poll;
3
4#[path = "../iour/mod.rs"]
5mod iour;
6
7pub(crate) mod op;
8
9#[cfg_attr(all(doc, docsrs), doc(cfg(all())))]
10pub use std::os::fd::{AsFd, AsRawFd, BorrowedFd, OwnedFd, RawFd};
11use std::{
12 io,
13 task::{Poll, Waker},
14 time::Duration,
15};
16
17use compio_log::warn;
18pub(crate) use iour::is_op_supported;
19pub use iour::{OpCode as IourOpCode, OpEntry};
20pub use poll::{Decision, OpCode as PollOpCode, OpType};
21
22pub use crate::driver_type::DriverType; use crate::{BufferPool, Key, ProactorBuilder};
24
25pub trait OpCode: PollOpCode + IourOpCode {}
29
30impl<T: PollOpCode + IourOpCode + ?Sized> OpCode for T {}
31
32#[allow(clippy::large_enum_variant)]
33enum FuseDriver {
34 Poll(poll::Driver),
35 IoUring(iour::Driver),
36}
37
38pub(crate) struct Driver {
40 fuse: FuseDriver,
41}
42
43impl Driver {
44 pub fn new(builder: &ProactorBuilder) -> io::Result<Self> {
46 let (ty, fallback) = match &builder.driver_type {
47 Some(t) => (*t, false),
48 None => (DriverType::suggest(), true),
49 };
50 match ty {
51 DriverType::Poll => Ok(Self {
52 fuse: FuseDriver::Poll(poll::Driver::new(builder)?),
53 }),
54 DriverType::IoUring => match iour::Driver::new(builder) {
55 Ok(driver) => Ok(Self {
56 fuse: FuseDriver::IoUring(driver),
57 }),
58 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 pub fn driver_type(&self) -> DriverType {
71 match &self.fuse {
72 FuseDriver::Poll(driver) => driver.driver_type(),
73 FuseDriver::IoUring(driver) => driver.driver_type(),
74 }
75 }
76
77 pub fn create_op<T: OpCode + 'static>(&self, op: T) -> Key<T> {
78 match &self.fuse {
79 FuseDriver::Poll(driver) => driver.create_op(op),
80 FuseDriver::IoUring(driver) => driver.create_op(op),
81 }
82 }
83
84 pub fn attach(&mut self, fd: RawFd) -> io::Result<()> {
85 match &mut self.fuse {
86 FuseDriver::Poll(driver) => driver.attach(fd),
87 FuseDriver::IoUring(driver) => driver.attach(fd),
88 }
89 }
90
91 pub fn cancel(&mut self, op: &mut Key<dyn OpCode>) {
92 match &mut self.fuse {
93 FuseDriver::Poll(driver) => driver.cancel(op),
94 FuseDriver::IoUring(driver) => driver.cancel(op),
95 }
96 }
97
98 pub fn push(&mut self, op: &mut Key<dyn OpCode>) -> Poll<io::Result<usize>> {
99 match &mut self.fuse {
100 FuseDriver::Poll(driver) => driver.push(op),
101 FuseDriver::IoUring(driver) => driver.push(op),
102 }
103 }
104
105 pub fn poll(&mut self, timeout: Option<Duration>) -> io::Result<()> {
106 match &mut self.fuse {
107 FuseDriver::Poll(driver) => driver.poll(timeout),
108 FuseDriver::IoUring(driver) => driver.poll(timeout),
109 }
110 }
111
112 pub fn waker(&self) -> Waker {
113 match &self.fuse {
114 FuseDriver::Poll(driver) => driver.waker(),
115 FuseDriver::IoUring(driver) => driver.waker(),
116 }
117 }
118
119 pub fn create_buffer_pool(
120 &mut self,
121 buffer_len: u16,
122 buffer_size: usize,
123 ) -> io::Result<BufferPool> {
124 match &mut self.fuse {
125 FuseDriver::IoUring(driver) => Ok(driver.create_buffer_pool(buffer_len, buffer_size)?),
126 FuseDriver::Poll(driver) => Ok(driver.create_buffer_pool(buffer_len, buffer_size)?),
127 }
128 }
129
130 pub unsafe fn release_buffer_pool(&mut self, buffer_pool: BufferPool) -> io::Result<()> {
134 unsafe {
135 match &mut self.fuse {
136 FuseDriver::Poll(driver) => driver.release_buffer_pool(buffer_pool),
137 FuseDriver::IoUring(driver) => driver.release_buffer_pool(buffer_pool),
138 }
139 }
140 }
141}
142
143impl AsRawFd for Driver {
144 fn as_raw_fd(&self) -> RawFd {
145 match &self.fuse {
146 FuseDriver::Poll(driver) => driver.as_raw_fd(),
147 FuseDriver::IoUring(driver) => driver.as_raw_fd(),
148 }
149 }
150}