monoio/utils/
uring_detect.rs1#[cfg(all(target_os = "linux", feature = "iouring"))]
4macro_rules! err_to_false {
5 ($e: expr) => {
6 match $e {
7 Ok(x) => x,
8 Err(_) => {
9 return false;
10 }
11 }
12 };
13}
14#[cfg(all(target_os = "linux", feature = "iouring"))]
15fn detect_uring_inner() -> bool {
16 let val = std::env::var("MONOIO_FORCE_LEGACY_DRIVER");
17 match val {
18 Ok(v) if matches!(v.to_ascii_lowercase().as_str(), "1" | "true" | "yes") => {
19 return false;
20 }
21 _ => {}
22 }
23
24 use io_uring::opcode::*;
25 auto_const_array::auto_const_array! {
26 const USED_OP: [u8; _] = [
27 Accept::CODE,
28 AsyncCancel::CODE,
29 Close::CODE,
30 Connect::CODE,
31 Fsync::CODE,
32 #[cfg(feature = "mkdirat")]
33 MkDirAt::CODE,
34 OpenAt::CODE,
35 PollAdd::CODE,
36 ProvideBuffers::CODE,
37 Read::CODE,
38 Readv::CODE,
39 Recv::CODE,
40 #[cfg(feature = "renameat")]
41 RenameAt::CODE,
42 Send::CODE,
43 SendMsg::CODE,
44 RecvMsg::CODE,
45 #[cfg(feature = "splice")]
46 Splice::CODE,
47 Statx::CODE,
48 #[cfg(feature = "symlinkat")]
49 SymlinkAt::CODE,
50 Timeout::CODE,
51 #[cfg(feature = "unlinkat")]
52 UnlinkAt::CODE,
53 Write::CODE,
54 Writev::CODE,
55 ];
56 }
57
58 let uring = err_to_false!(io_uring::IoUring::new(2));
59 let mut probe = io_uring::Probe::new();
60 err_to_false!(uring.submitter().register_probe(&mut probe));
61 USED_OP.iter().all(|op| probe.is_supported(*op))
62}
63
64#[cfg(all(target_os = "linux", feature = "iouring"))]
66pub fn detect_uring() -> bool {
67 static mut URING_SUPPORTED: bool = false;
68 static INIT: std::sync::Once = std::sync::Once::new();
69
70 unsafe {
71 INIT.call_once(|| {
72 URING_SUPPORTED = detect_uring_inner();
73 });
74 URING_SUPPORTED
75 }
76}
77
78#[cfg(not(all(target_os = "linux", feature = "iouring")))]
80pub fn detect_uring() -> bool {
81 false
82}
83
84#[cfg(test)]
85mod tests {
86 #[cfg(all(target_os = "linux", feature = "iouring"))]
87 #[test]
88 fn test_detect() {
89 assert!(
90 super::detect_uring(),
91 "io_uring or ops not supported on current platform"
92 )
93 }
94}