1
0
Fork 0
forked from wry/wry

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:
Julian Orth 2022-12-31 17:55:58 +01:00
parent 2db0ee8995
commit 9812a02f87
55 changed files with 900 additions and 672 deletions

View file

@ -26,12 +26,13 @@ use {
rc::{Rc, Weak},
},
thiserror::Error,
uapi::{c, Errno, OwnedFd, Pod, Ustring},
uapi::{c, OwnedFd, Pod, Ustring},
};
use crate::{
backend,
utils::{errorfmt::ErrorFmt, stack::Stack, syncqueue::SyncQueue, vec_ext::VecExt},
io_uring::{IoUring, IoUringError},
utils::{buf::Buf, errorfmt::ErrorFmt, stack::Stack, syncqueue::SyncQueue, vec_ext::VecExt},
video::{
dmabuf::DmaBuf,
drm::sys::{get_version, DRM_CAP_CURSOR_HEIGHT, DRM_CAP_CURSOR_WIDTH},
@ -100,7 +101,7 @@ pub enum DrmError {
#[error("Could not convert prime fd to gem handle")]
GemHandle(#[source] OsError),
#[error("Could not read events from the drm fd")]
ReadEvents(#[source] OsError),
ReadEvents(#[source] IoUringError),
#[error("Read invalid data from drm device")]
InvalidRead,
#[error("Could not determine the drm version")]
@ -179,7 +180,8 @@ pub struct DrmMaster {
u64_bufs: Stack<Vec<u64>>,
gem_handles: RefCell<AHashMap<u32, Weak<GemHandle>>>,
events: SyncQueue<DrmEvent>,
buf: RefCell<Box<[MaybeUninit<u8>; 1024]>>,
ring: Rc<IoUring>,
buf: RefCell<Buf>,
}
impl Debug for DrmMaster {
@ -197,14 +199,15 @@ impl Deref for DrmMaster {
}
impl DrmMaster {
pub fn new(fd: Rc<OwnedFd>) -> Self {
pub fn new(ring: &Rc<IoUring>, fd: Rc<OwnedFd>) -> Self {
Self {
drm: Drm { fd },
u32_bufs: Default::default(),
u64_bufs: Default::default(),
gem_handles: Default::default(),
events: Default::default(),
buf: RefCell::new(Box::new([MaybeUninit::uninit(); 1024])),
ring: ring.clone(),
buf: RefCell::new(Buf::new(1024)),
}
}
@ -370,13 +373,13 @@ impl DrmMaster {
}
}
pub fn event(&self) -> Result<Option<DrmEvent>, DrmError> {
#[allow(clippy::await_holding_refcell_ref)]
pub async fn event(&self) -> Result<Option<DrmEvent>, DrmError> {
if self.events.is_empty() {
let mut buf = self.buf.borrow_mut();
let mut buf = match uapi::read(self.raw(), buf.as_mut_slice()) {
Ok(b) => b,
Err(Errno(c::EAGAIN)) => return Ok(None),
Err(e) => return Err(DrmError::ReadEvents(e.into())),
let mut buf = match self.ring.read(self.drm.fd(), buf.clone()).await {
Ok(n) => &buf[..n],
Err(e) => return Err(DrmError::ReadEvents(e)),
};
while buf.len() > 0 {
let header: drm_event = match uapi::pod_read_init(buf) {
@ -402,7 +405,7 @@ impl DrmMaster {
}
_ => {}
}
buf = &mut buf[len as usize..];
buf = &buf[len as usize..];
}
}
Ok(self.events.pop())