1#![cfg(target_os = "linux")]
2
3pub mod driver;
4pub mod sys;
5
6pub(crate) use dope_core::{Fd, FixedFd};
7
8pub use driver::config::DriverConfig;
9pub use driver::handle::new_driver;
10pub use driver::{
11 CqeKind, CqeRouter, CqeView, CurrentSlot, Driver, ProvidedRing, RecvMsgOut, Request, current,
12 current_driver_mut, set_current,
13};
14
15#[derive(Clone, Copy, Debug, Default)]
16pub struct UringBackend;
17
18impl dope_core::driver::Backend for UringBackend {
19 type Driver = driver::Driver;
20 type Config = DriverConfig;
21 type RecvMsgOut = driver::RecvMsgOut;
22 type ProvidedBuf = driver::ProvidedBuf;
23
24 fn new_driver(cfg: Self::Config) -> std::io::Result<Self::Driver> {
25 new_driver(cfg)
26 }
27}
28
29struct CompletionShim<'a, R: dope_core::driver::CompletionRouter<UringBackend>> {
30 inner: &'a mut R,
31}
32
33impl<R: dope_core::driver::CompletionRouter<UringBackend>> CqeRouter for CompletionShim<'_, R> {
34 #[inline(always)]
35 fn on_cqe(&mut self, driver: &mut Driver, cqe: CqeView) {
36 use dope_core::driver::Completion;
37 let ev = match cqe.kind() {
38 CqeKind::Accept(t) => Completion::Accept {
39 token: t,
40 result: cqe.result,
41 more: cqe.more(),
42 },
43 CqeKind::Recv(t) => Completion::Recv {
44 token: t,
45 result: cqe.result,
46 more: cqe.more(),
47 bid: cqe.buffer_select(),
48 },
49 CqeKind::Write(t) => Completion::Write {
50 token: t,
51 result: cqe.result,
52 notif: cqe.notif(),
53 },
54 };
55 self.inner.on_complete(driver, ev);
56 }
57}
58
59thread_local! {
60 static AUX: std::cell::Cell<Option<dope_core::driver::ExternalDispatch<UringBackend>>> =
61 const { std::cell::Cell::new(None) };
62}
63
64impl dope_core::driver::CompletionBackend for UringBackend {
65 type Token = sys::token::Token;
66
67 #[inline(always)]
68 fn current_slot() -> Option<dope_core::driver::CurrentSlot<Self>> {
69 driver::current()
70 }
71
72 #[inline(always)]
73 fn set_slot(slot: Option<dope_core::driver::CurrentSlot<Self>>) {
74 driver::set_current(slot);
75 }
76
77 #[inline(always)]
78 fn install_external(
79 aux: Option<dope_core::driver::ExternalDispatch<Self>>,
80 ) -> Option<dope_core::driver::ExternalDispatch<Self>> {
81 AUX.with(|c| c.replace(aux))
82 }
83
84 #[inline(always)]
85 fn current_external() -> Option<dope_core::driver::ExternalDispatch<Self>> {
86 AUX.with(|c| c.get())
87 }
88
89 #[inline(always)]
90 fn drive_with<R: dope_core::driver::CompletionRouter<Self>>(
91 driver: &mut Self::Driver,
92 router: &mut R,
93 ) -> std::io::Result<bool> {
94 let mut shim = CompletionShim { inner: router };
95 driver.drive_with(&mut shim)
96 }
97
98 #[inline(always)]
99 fn dispatch_completions<R: dope_core::driver::CompletionRouter<Self>>(
100 driver: &mut Self::Driver,
101 router: &mut R,
102 ) {
103 let mut shim = CompletionShim { inner: router };
104 driver.dispatch_cqes(&mut shim)
105 }
106}
107
108pub(crate) use sys::Sqe;
109pub use sys::token::Token;