dope_uring/driver/
ring.rs1use std::{io, time::Duration};
2
3use io_uring::{CompletionQueue, IoUring, Submitter, opcode, types};
4
5use crate::driver::wire;
6
7pub struct Ring {
8 inner: IoUring,
9}
10
11impl Ring {
12 pub(crate) fn new(uring: IoUring) -> Self {
13 Self { inner: uring }
14 }
15
16 pub(crate) fn submitter<'a>(&'a self) -> Submitter<'a> {
17 self.inner.submitter()
18 }
19
20 pub(crate) fn completion<'a>(&'a mut self) -> CompletionQueue<'a> {
21 self.inner.completion()
22 }
23
24 pub(in crate::driver) fn submission_len(&mut self) -> usize {
25 self.inner.submission().len()
26 }
27
28 pub(in crate::driver) fn is_full(&mut self) -> bool {
29 self.inner.submission().is_full()
30 }
31
32 pub(in crate::driver) fn has_submission(&mut self) -> bool {
33 !self.inner.submission().is_empty()
34 }
35
36 pub(in crate::driver) fn has_completion(&mut self) -> bool {
37 !self.inner.completion().is_empty()
38 }
39
40 pub(in crate::driver) fn submit_and_wait(&mut self, min_complete: u32) -> io::Result<()> {
41 self.inner.submit_and_wait(min_complete as usize)?;
42 Ok(())
43 }
44
45 pub(in crate::driver) fn submit(&mut self) -> io::Result<usize> {
46 let before = self.submission_len();
47 self.inner
48 .submit()
49 .map(|_| before.saturating_sub(self.submission_len()))
50 }
51
52 pub(in crate::driver) fn submit_with_timeout(
53 &mut self,
54 min_complete: u32,
55 duration: Duration,
56 ) -> io::Result<()> {
57 let ts = types::Timespec::from(duration);
58 let args = types::SubmitArgs::new().timespec(&ts);
59 let want = min_complete as usize;
60 match self.inner.submitter().submit_with_args(want, &args) {
61 Ok(_) => Ok(()),
62 Err(e) if e.raw_os_error() == Some(libc::ETIME) => Ok(()),
63 Err(e) => Err(e),
64 }
65 }
66
67 pub(in crate::driver) fn try_push_arm(&mut self, sqe: io_uring::squeue::Entry) -> bool {
68 unsafe {
69 let mut sq = self.inner.submission();
70 sq.push(&sqe).is_ok()
71 }
72 }
73
74 pub(in crate::driver) fn push(&mut self, sqe: &io_uring::squeue::Entry) -> bool {
75 unsafe {
76 let mut sq = self.inner.submission();
77 sq.push(sqe).is_ok()
78 }
79 }
80
81 pub(in crate::driver) fn submit_cancel(&mut self, target_user_data: u64) {
82 let sqe = opcode::AsyncCancel::new(target_user_data)
83 .build()
84 .user_data(wire::ignore());
85
86 unsafe {
87 let mut sq = self.inner.submission();
88 if sq.push(&sqe).is_ok() {
89 return;
90 }
91 }
92 if let Err(e) = self.submit() {
93 panic!("dope invariant violated: cancel submit failed: {e}");
94 }
95 unsafe {
96 let mut sq = self.inner.submission();
97 if sq.push(&sqe).is_err() {
98 panic!("dope invariant violated: cancel SQE enqueue failed after submit");
99 }
100 }
101 }
102}