Skip to main content

dope_uring/
lib.rs

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;