#![cfg(target_os = "linux")]
pub mod driver;
pub mod sys;
pub(crate) use dope_core::{Fd, FixedFd};
pub use driver::config::DriverConfig;
pub use driver::handle::new_driver;
pub use driver::{
CqeKind, CqeRouter, CqeView, CurrentSlot, Driver, ProvidedRing, RecvMsgOut, Request, current,
current_driver_mut, set_current,
};
#[derive(Clone, Copy, Debug, Default)]
pub struct UringBackend;
impl dope_core::driver::Backend for UringBackend {
type Driver = driver::Driver;
type Config = DriverConfig;
type RecvMsgOut = driver::RecvMsgOut;
type ProvidedBuf = driver::ProvidedBuf;
fn new_driver(cfg: Self::Config) -> std::io::Result<Self::Driver> {
new_driver(cfg)
}
}
struct CompletionShim<'a, R: dope_core::driver::CompletionRouter<UringBackend>> {
inner: &'a mut R,
}
impl<R: dope_core::driver::CompletionRouter<UringBackend>> CqeRouter for CompletionShim<'_, R> {
#[inline(always)]
fn on_cqe(&mut self, driver: &mut Driver, cqe: CqeView) {
use dope_core::driver::Completion;
let ev = match cqe.kind() {
CqeKind::Accept(t) => Completion::Accept {
token: t,
result: cqe.result,
more: cqe.more(),
},
CqeKind::Recv(t) => Completion::Recv {
token: t,
result: cqe.result,
more: cqe.more(),
bid: cqe.buffer_select(),
},
CqeKind::Write(t) => Completion::Write {
token: t,
result: cqe.result,
notif: cqe.notif(),
},
};
self.inner.on_complete(driver, ev);
}
}
thread_local! {
static AUX: std::cell::Cell<Option<dope_core::driver::ExternalDispatch<UringBackend>>> =
const { std::cell::Cell::new(None) };
}
impl dope_core::driver::CompletionBackend for UringBackend {
type Token = sys::token::Token;
#[inline(always)]
fn current_slot() -> Option<dope_core::driver::CurrentSlot<Self>> {
driver::current()
}
#[inline(always)]
fn set_slot(slot: Option<dope_core::driver::CurrentSlot<Self>>) {
driver::set_current(slot);
}
#[inline(always)]
fn install_external(
aux: Option<dope_core::driver::ExternalDispatch<Self>>,
) -> Option<dope_core::driver::ExternalDispatch<Self>> {
AUX.with(|c| c.replace(aux))
}
#[inline(always)]
fn current_external() -> Option<dope_core::driver::ExternalDispatch<Self>> {
AUX.with(|c| c.get())
}
#[inline(always)]
fn drive_with<R: dope_core::driver::CompletionRouter<Self>>(
driver: &mut Self::Driver,
router: &mut R,
) -> std::io::Result<bool> {
let mut shim = CompletionShim { inner: router };
driver.drive_with(&mut shim)
}
#[inline(always)]
fn dispatch_completions<R: dope_core::driver::CompletionRouter<Self>>(
driver: &mut Self::Driver,
router: &mut R,
) {
let mut shim = CompletionShim { inner: router };
driver.dispatch_cqes(&mut shim)
}
}
pub(crate) use sys::Sqe;
pub use sys::token::Token;