io: use io_uring for all io
There should no longer be any - read - write - connect - sendmsg - recvmsg - accept calls in the codebase. Previously we were using a mix of io_uring and these calls which had some negative effects: Since we were using the old system calls, we had to set the file descriptors to non-blocking. But our io_uring code did not handle EAGAIN. This lead to programs sometimes being killed when the wayland IO was actually blocking. Now all file descriptors are set to blocking, but io_uring makes it non-blocking from our perspective. The one exception are evdev files because they are read via libinput and libinput uses the old system calls.
This commit is contained in:
parent
2db0ee8995
commit
9812a02f87
55 changed files with 900 additions and 672 deletions
177
src/utils/buf.rs
177
src/utils/buf.rs
|
|
@ -2,17 +2,25 @@ use {
|
|||
crate::utils::{numcell::NumCell, ptr_ext::PtrExt},
|
||||
std::{
|
||||
alloc::Layout,
|
||||
cmp,
|
||||
collections::Bound,
|
||||
fmt::Arguments,
|
||||
io::{self, Write},
|
||||
marker::PhantomData,
|
||||
mem,
|
||||
ops::{Deref, DerefMut, Range, RangeBounds},
|
||||
ptr::NonNull,
|
||||
slice,
|
||||
},
|
||||
uapi::Pod,
|
||||
};
|
||||
|
||||
const METADATA_SIZE: u32 = 8;
|
||||
const METADATA_ALIGN: usize = 4;
|
||||
const SIZE_OFF: u32 = 0;
|
||||
const RC_OFF: u32 = 4;
|
||||
const RC_OFF_INV: u32 = METADATA_SIZE - RC_OFF;
|
||||
const SIZE_OFF_INV: u32 = METADATA_SIZE - SIZE_OFF;
|
||||
|
||||
pub struct Buf {
|
||||
storage: NonNull<u8>,
|
||||
|
|
@ -118,9 +126,55 @@ impl Buf {
|
|||
self.len32() as _
|
||||
}
|
||||
|
||||
fn size32(&self) -> u32 {
|
||||
unsafe {
|
||||
*self
|
||||
.storage
|
||||
.as_ptr()
|
||||
.sub(SIZE_OFF_INV as _)
|
||||
.cast::<u32>()
|
||||
.deref()
|
||||
}
|
||||
}
|
||||
|
||||
pub fn cap32(&self) -> u32 {
|
||||
self.size32() - METADATA_SIZE
|
||||
}
|
||||
|
||||
pub fn as_ptr(&self) -> *mut u8 {
|
||||
unsafe { self.storage.as_ptr().add(self.range.start as _) }
|
||||
}
|
||||
|
||||
pub fn write_fmt(&mut self, args: Arguments) -> Result<Self, io::Error> {
|
||||
let cap = self.len();
|
||||
let mut buf = self.deref_mut();
|
||||
buf.write_fmt(args)?;
|
||||
let len = cap - buf.len();
|
||||
Ok(self.slice(..len))
|
||||
}
|
||||
|
||||
pub fn into_full(self) -> Self {
|
||||
let new = Self {
|
||||
storage: self.storage,
|
||||
range: 0..self.cap32(),
|
||||
};
|
||||
mem::forget(self);
|
||||
new
|
||||
}
|
||||
|
||||
fn as_slice(&self) -> &[u8] {
|
||||
unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
|
||||
}
|
||||
|
||||
fn as_slice_mut(&mut self) -> &mut [u8] {
|
||||
unsafe { slice::from_raw_parts_mut(self.as_ptr(), self.len()) }
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for Buf {
|
||||
fn default() -> Self {
|
||||
Self::new(0)
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for Buf {
|
||||
|
|
@ -128,14 +182,14 @@ impl Deref for Buf {
|
|||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.assert_unique();
|
||||
unsafe { slice::from_raw_parts(self.as_ptr(), self.len()) }
|
||||
self.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for Buf {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.assert_unique();
|
||||
unsafe { slice::from_raw_parts_mut(self.as_ptr(), self.len()) }
|
||||
self.as_slice_mut()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -153,3 +207,122 @@ impl Drop for Buf {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct DynamicBuf {
|
||||
buf: Buf,
|
||||
len: usize,
|
||||
}
|
||||
|
||||
impl DynamicBuf {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
buf: Buf::new(0),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn from_buf(buf: Buf) -> Self {
|
||||
buf.assert_unique();
|
||||
Self {
|
||||
buf: buf.into_full(),
|
||||
len: 0,
|
||||
}
|
||||
}
|
||||
|
||||
pub fn unwrap(mut self) -> Buf {
|
||||
self.buf.slice(..self.len)
|
||||
}
|
||||
|
||||
pub fn len(&self) -> usize {
|
||||
self.len
|
||||
}
|
||||
|
||||
pub fn reserve(&mut self, n: usize) {
|
||||
if self.buf.len() - self.len < n {
|
||||
let cap = self.len.checked_add(n).unwrap();
|
||||
let cap = cmp::max(self.buf.len() * 2, cap);
|
||||
let mut new = Buf::new(cap);
|
||||
new[..self.len].copy_from_slice(&self.buf[..self.len]);
|
||||
self.buf = new;
|
||||
}
|
||||
}
|
||||
|
||||
pub fn extend_from_slice(&mut self, buf: &[u8]) {
|
||||
self.reserve(buf.len());
|
||||
self.buf.as_slice_mut()[self.len..self.len + buf.len()].copy_from_slice(buf);
|
||||
self.len += buf.len();
|
||||
}
|
||||
|
||||
pub fn push(&mut self, b: u8) {
|
||||
self.extend_from_slice(&[b]);
|
||||
}
|
||||
|
||||
pub fn clear(&mut self) {
|
||||
self.len = 0;
|
||||
}
|
||||
|
||||
pub fn borrow(&mut self) -> BorrowedBuf<'_> {
|
||||
BorrowedBuf {
|
||||
buf: self.buf.slice(..self.len),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub struct BorrowedBuf<'a> {
|
||||
pub buf: Buf,
|
||||
_phantom: PhantomData<&'a mut DynamicBuf>,
|
||||
}
|
||||
|
||||
impl<'a> Drop for BorrowedBuf<'a> {
|
||||
fn drop(&mut self) {
|
||||
assert_eq!(self.buf.rc().get(), 2);
|
||||
}
|
||||
}
|
||||
|
||||
impl Write for DynamicBuf {
|
||||
fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
|
||||
self.extend_from_slice(buf);
|
||||
Ok(buf.len())
|
||||
}
|
||||
|
||||
fn flush(&mut self) -> io::Result<()> {
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
|
||||
impl Deref for DynamicBuf {
|
||||
type Target = [u8];
|
||||
|
||||
fn deref(&self) -> &Self::Target {
|
||||
self.buf.as_slice()
|
||||
}
|
||||
}
|
||||
|
||||
impl DerefMut for DynamicBuf {
|
||||
fn deref_mut(&mut self) -> &mut Self::Target {
|
||||
self.buf.as_slice_mut()
|
||||
}
|
||||
}
|
||||
|
||||
pub struct TypedBuf<T: Pod> {
|
||||
buf: Buf,
|
||||
_phantom: PhantomData<T>,
|
||||
}
|
||||
|
||||
impl<T: Pod> TypedBuf<T> {
|
||||
pub fn new() -> Self {
|
||||
Self {
|
||||
buf: Buf::new(mem::size_of::<T>()),
|
||||
_phantom: Default::default(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn buf(&mut self) -> Buf {
|
||||
self.buf.clone()
|
||||
}
|
||||
|
||||
pub fn t(&self) -> T {
|
||||
uapi::pod_read(&self.buf[..]).unwrap()
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue