jay-compositor 1.15.0

The Jay compositor
use crate::io_uring::IoUring;
use crate::utils::asyncevent::AsyncEvent;
use crate::utils::errorfmt::ErrorFmt;
use crate::utils::event_listener::EventSource;
use crate::utils::timer::TimerFd;
use std::rc::Rc;
use std::time::Duration;
use uapi::c;

pub async fn run_const_clock<T, F>(
    duration: Duration,
    ring: &Rc<IoUring>,
    source: &EventSource<T>,
    mut f: F,
) where
    T: ?Sized,
    F: FnMut(Rc<T>),
{
    let timer = match TimerFd::new(c::CLOCK_MONOTONIC) {
        Ok(fd) => fd,
        Err(e) => {
            log::error!("Could not create timerfd: {}", ErrorFmt(e));
            return;
        }
    };
    if let Err(e) = timer.program(Some(duration), Some(duration)) {
        log::error!("Could not program timerfd: {}", ErrorFmt(e));
        return;
    }
    let ae = Rc::new(AsyncEvent::default());
    loop {
        if let Err(e) = timer.expired(&ring).await {
            log::error!("Could not wait for timerfd to expire: {}", ErrorFmt(e));
            return;
        }
        let mut dispatched_any = false;
        source.for_each(|el| {
            dispatched_any = true;
            f(el);
        });
        if !dispatched_any {
            let ae2 = ae.clone();
            source.on_attach(Box::new(move || ae2.trigger()));
            ae.triggered().await;
        }
    }
}