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

@ -8,12 +8,14 @@ use {
},
io_uring::{IoUring, IoUringError},
utils::{
buf::DynamicBuf,
bufio::{BufIo, BufIoError},
clonecell::CloneCell,
copyhashmap::CopyHashMap,
numcell::NumCell,
oserror::OsError,
run_toplevel::RunToplevel,
stack::Stack,
vecstorage::VecStorage,
xrd::{xrd, XRD},
},
@ -89,11 +91,11 @@ pub enum DbusError {
#[error("Could not create a socket")]
Socket(#[source] OsError),
#[error("Could not connect")]
Connect(#[source] OsError),
Connect(#[source] IoUringError),
#[error("Could not write to the dbus socket")]
WriteError(#[source] OsError),
WriteError(#[source] IoUringError),
#[error("Could not read from the dbus socket")]
ReadError(#[source] OsError),
ReadError(#[source] IoUringError),
#[error("timeout")]
IoUringError(#[source] Box<IoUringError>),
#[error("Server did not accept our authentication")]
@ -169,21 +171,25 @@ impl Dbus {
self.session.clear();
}
pub fn system(&self) -> Result<Rc<DbusSocket>, DbusError> {
self.system.get(
&self.eng,
&self.ring,
"/var/run/dbus/system_bus_socket",
"System bus",
)
pub async fn system(&self) -> Result<Rc<DbusSocket>, DbusError> {
self.system
.get(
&self.eng,
&self.ring,
"/var/run/dbus/system_bus_socket",
"System bus",
)
.await
}
pub fn session(&self) -> Result<Rc<DbusSocket>, DbusError> {
pub async fn session(&self) -> Result<Rc<DbusSocket>, DbusError> {
let sba = match self.user_path.as_deref() {
None => return Err(DbusError::SessionBusAddressNotSet),
Some(sba) => sba,
};
self.session.get(&self.eng, &self.ring, sba, "Session bus")
self.session
.get(&self.eng, &self.ring, sba, "Session bus")
.await
}
}
@ -203,6 +209,7 @@ pub struct DbusSocket {
bus_name: &'static str,
fd: Rc<OwnedFd>,
ring: Rc<IoUring>,
in_bufs: Stack<Vec<u8>>,
bufio: Rc<BufIo>,
eng: Rc<AsyncEngine>,
next_serial: NumCell<u32>,
@ -361,7 +368,7 @@ pub struct Parser<'a> {
pub struct Formatter<'a> {
fds: &'a mut Vec<Rc<OwnedFd>>,
buf: &'a mut Vec<u8>,
buf: &'a mut DynamicBuf,
}
pub unsafe trait Message<'a>: Sized + 'a {
@ -469,7 +476,7 @@ impl<T: Message<'static>> Reply<T> {
impl<T: Message<'static>> Drop for Reply<T> {
fn drop(&mut self) {
self.socket.bufio.add_buf(mem::take(&mut self.buf));
self.socket.in_bufs.push(mem::take(&mut self.buf));
}
}