Skip to main content

rio/io_uring/
mod.rs

1use std::{
2    cell::UnsafeCell,
3    convert::TryFrom,
4    fs::File,
5    io,
6    net::{TcpListener, TcpStream},
7    ops::Neg,
8    os::unix::io::{AsRawFd, FromRawFd},
9    sync::{
10        atomic::{
11            AtomicU32, AtomicU64,
12            Ordering::{Acquire, Relaxed, Release},
13        },
14        Arc, Condvar, Mutex,
15    },
16    mem::MaybeUninit
17};
18
19use super::{
20    pair, AsIoVec, AsIoVecMut, Completion, Filler, FromCqe,
21    Measure, M,
22};
23
24mod config;
25mod constants;
26mod cq;
27mod in_flight;
28mod kernel_types;
29mod sq;
30mod syscall;
31mod ticket_queue;
32mod uring;
33
34pub(crate) use {
35    constants::*,
36    cq::Cq,
37    in_flight::InFlight,
38    kernel_types::{
39        io_uring_cqe, io_uring_params, io_uring_sqe,
40    },
41    sq::Sq,
42    syscall::{enter, setup},
43    ticket_queue::TicketQueue,
44};
45
46pub use {
47    config::Config,
48    uring::{Rio, Uring},
49};
50
51/// Specify whether `io_uring` should
52/// run operations in a specific order.
53/// By default, it will run independent
54/// operations in any order it can to
55/// speed things up. This can be constrained
56/// by either submitting chains of `Link`
57/// events, which are executed one after the other,
58/// or by specifying the `Drain` ordering
59/// which causes all previously submitted operations
60/// to complete first.
61#[derive(Clone, Debug, Copy)]
62pub enum Ordering {
63    /// No ordering requirements
64    None,
65    /// `Ordering::Link` causes the next
66    /// submitted operation to wait until
67    /// this one finishes. Useful for
68    /// things like file copy, fsync-after-write,
69    /// or proxies.
70    Link,
71    /// `Ordering::Drain` causes all previously
72    /// submitted operations to complete before
73    /// this one begins.
74    Drain,
75}
76
77fn uring_mmap(
78    size: usize,
79    ring_fd: i32,
80    offset: i64,
81) -> io::Result<*mut libc::c_void> {
82    #[allow(unsafe_code)]
83    let ptr = unsafe {
84        libc::mmap(
85            std::ptr::null_mut(),
86            size,
87            libc::PROT_READ | libc::PROT_WRITE,
88            libc::MAP_SHARED | libc::MAP_POPULATE,
89            ring_fd,
90            offset,
91        )
92    };
93
94    if ptr.is_null() || ptr == libc::MAP_FAILED {
95        let mut err = io::Error::last_os_error();
96        if let Some(12) = err.raw_os_error() {
97            err = io::Error::new(
98                io::ErrorKind::Other,
99                "Not enough lockable memory. You probably \
100                 need to raise the memlock rlimit, which \
101                 often defaults to a pretty low number.",
102            );
103        }
104        return Err(err);
105    }
106
107    Ok(ptr)
108}
109
110impl FromCqe for TcpStream {
111    fn from_cqe(cqe: io_uring_cqe) -> TcpStream {
112        #[allow(unsafe_code)]
113        unsafe {
114            TcpStream::from_raw_fd(cqe.res)
115        }
116    }
117}