sighand: rebase from EventLoop onto AsyncEngine
This commit is contained in:
parent
4d8a340cd0
commit
3037ee439c
2 changed files with 36 additions and 41 deletions
|
|
@ -115,11 +115,11 @@ fn start_compositor2(
|
||||||
render::init()?;
|
render::init()?;
|
||||||
clientmem::init()?;
|
clientmem::init()?;
|
||||||
let el = EventLoop::new()?;
|
let el = EventLoop::new()?;
|
||||||
sighand::install(&el)?;
|
|
||||||
let xkb_ctx = XkbContext::new().unwrap();
|
let xkb_ctx = XkbContext::new().unwrap();
|
||||||
let xkb_keymap = xkb_ctx.keymap_from_str(include_str!("keymap.xkb")).unwrap();
|
let xkb_keymap = xkb_ctx.keymap_from_str(include_str!("keymap.xkb")).unwrap();
|
||||||
let engine = AsyncEngine::install(&el)?;
|
let engine = AsyncEngine::install(&el)?;
|
||||||
let ring = IoUring::new(&engine, 32)?;
|
let ring = IoUring::new(&engine, 32)?;
|
||||||
|
let _signal_future = sighand::install(&el, &engine, &ring)?;
|
||||||
let wheel = Wheel::new(&engine, &ring)?;
|
let wheel = Wheel::new(&engine, &ring)?;
|
||||||
let (_run_toplevel_future, run_toplevel) = RunToplevel::install(&engine);
|
let (_run_toplevel_future, run_toplevel) = RunToplevel::install(&engine);
|
||||||
let node_ids = NodeIds::default();
|
let node_ids = NodeIds::default();
|
||||||
|
|
|
||||||
|
|
@ -1,25 +1,30 @@
|
||||||
use {
|
use {
|
||||||
crate::event_loop::{EventLoop, EventLoopDispatcher, EventLoopError, EventLoopId},
|
crate::{
|
||||||
std::{error::Error, rc::Rc},
|
async_engine::{AsyncEngine, SpawnedFuture},
|
||||||
|
event_loop::{EventLoop, EventLoopError},
|
||||||
|
io_uring::IoUring,
|
||||||
|
utils::{errorfmt::ErrorFmt, oserror::OsError},
|
||||||
|
},
|
||||||
|
std::rc::Rc,
|
||||||
thiserror::Error,
|
thiserror::Error,
|
||||||
uapi::{c, Errno, OwnedFd},
|
uapi::{c, Errno, OwnedFd},
|
||||||
};
|
};
|
||||||
|
|
||||||
#[derive(Debug, Error)]
|
#[derive(Debug, Error)]
|
||||||
pub enum SighandError {
|
pub enum SighandError {
|
||||||
#[error("The signal fd is in an error state")]
|
|
||||||
ErrorEvent,
|
|
||||||
#[error("Could not read from the signal fd")]
|
|
||||||
ReadFailed(#[source] crate::utils::oserror::OsError),
|
|
||||||
#[error("Could not block the signalfd signals")]
|
#[error("Could not block the signalfd signals")]
|
||||||
BlockFailed(#[source] crate::utils::oserror::OsError),
|
BlockFailed(#[source] OsError),
|
||||||
#[error("Could not create a signalfd")]
|
#[error("Could not create a signalfd")]
|
||||||
CreateFailed(#[source] crate::utils::oserror::OsError),
|
CreateFailed(#[source] OsError),
|
||||||
#[error("The event loop caused an error")]
|
#[error("The event loop caused an error")]
|
||||||
EventLoopError(#[from] EventLoopError),
|
EventLoopError(#[from] EventLoopError),
|
||||||
}
|
}
|
||||||
|
|
||||||
pub fn install(el: &Rc<EventLoop>) -> Result<(), SighandError> {
|
pub fn install(
|
||||||
|
el: &Rc<EventLoop>,
|
||||||
|
eng: &Rc<AsyncEngine>,
|
||||||
|
ring: &Rc<IoUring>,
|
||||||
|
) -> Result<SpawnedFuture<()>, SighandError> {
|
||||||
let mut set: c::sigset_t = uapi::pod_zeroed();
|
let mut set: c::sigset_t = uapi::pod_zeroed();
|
||||||
uapi::sigaddset(&mut set, c::SIGINT).unwrap();
|
uapi::sigaddset(&mut set, c::SIGINT).unwrap();
|
||||||
uapi::sigaddset(&mut set, c::SIGTERM).unwrap();
|
uapi::sigaddset(&mut set, c::SIGTERM).unwrap();
|
||||||
|
|
@ -28,51 +33,41 @@ pub fn install(el: &Rc<EventLoop>) -> Result<(), SighandError> {
|
||||||
return Err(SighandError::BlockFailed(e.into()));
|
return Err(SighandError::BlockFailed(e.into()));
|
||||||
}
|
}
|
||||||
let fd = match uapi::signalfd_new(&set, c::SFD_CLOEXEC | c::SFD_NONBLOCK) {
|
let fd = match uapi::signalfd_new(&set, c::SFD_CLOEXEC | c::SFD_NONBLOCK) {
|
||||||
Ok(fd) => fd,
|
Ok(fd) => Rc::new(fd),
|
||||||
Err(e) => return Err(SighandError::CreateFailed(e.into())),
|
Err(e) => return Err(SighandError::CreateFailed(e.into())),
|
||||||
};
|
};
|
||||||
let id = el.id();
|
Ok(eng.spawn(handle_signals(fd, ring.clone(), el.clone())))
|
||||||
let sh = Rc::new(Sighand {
|
|
||||||
fd,
|
|
||||||
id,
|
|
||||||
el: el.clone(),
|
|
||||||
});
|
|
||||||
el.insert(id, Some(sh.fd.raw()), c::EPOLLIN, sh)?;
|
|
||||||
Ok(())
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct Sighand {
|
async fn handle_signals(fd: Rc<OwnedFd>, ring: Rc<IoUring>, el: Rc<EventLoop>) {
|
||||||
fd: OwnedFd,
|
let mut siginfo: c::signalfd_siginfo = uapi::pod_zeroed();
|
||||||
id: EventLoopId,
|
loop {
|
||||||
el: Rc<EventLoop>,
|
if let Err(e) = ring.readable(&fd).await {
|
||||||
}
|
log::error!(
|
||||||
|
"Could not wait for signal fd to become readable: {}",
|
||||||
impl EventLoopDispatcher for Sighand {
|
ErrorFmt(e)
|
||||||
fn dispatch(self: Rc<Self>, _fd: Option<i32>, events: i32) -> Result<(), Box<dyn Error>> {
|
);
|
||||||
if events & (c::EPOLLERR | c::EPOLLHUP) != 0 {
|
return;
|
||||||
return Err(Box::new(SighandError::ErrorEvent));
|
|
||||||
}
|
}
|
||||||
let mut sigfd: c::signalfd_siginfo = uapi::pod_zeroed();
|
|
||||||
loop {
|
loop {
|
||||||
if let Err(e) = uapi::read(self.fd.raw(), &mut sigfd) {
|
if let Err(e) = uapi::read(fd.raw(), &mut siginfo) {
|
||||||
match e {
|
match e {
|
||||||
Errno(c::EAGAIN) => break,
|
Errno(c::EAGAIN) => break,
|
||||||
_ => return Err(Box::new(SighandError::ReadFailed(e.into()))),
|
_ => {
|
||||||
|
log::error!(
|
||||||
|
"Could not read from signal fd: {}",
|
||||||
|
ErrorFmt(OsError::from(e))
|
||||||
|
);
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let sig = sigfd.ssi_signo as i32;
|
let sig = siginfo.ssi_signo as i32;
|
||||||
log::info!("Received signal {}", sig);
|
log::info!("Received signal {}", sig);
|
||||||
if matches!(sig, c::SIGINT | c::SIGTERM) {
|
if matches!(sig, c::SIGINT | c::SIGTERM) {
|
||||||
log::info!("Exiting");
|
log::info!("Exiting");
|
||||||
self.el.stop();
|
el.stop();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Drop for Sighand {
|
|
||||||
fn drop(&mut self) {
|
|
||||||
let _ = self.el.remove(self.id);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue