ipmb 0.8.5

Inter-process message bus
Documentation
use super::Fd;
use std::{ffi, mem, time::Duration};

pub struct IoMultiplexing {
    fd: Fd,
    pub(crate) waker_fd: Fd,
}

impl IoMultiplexing {
    pub fn new() -> Self {
        let fd = unsafe {
            let fd = libc::epoll_create1(0);
            assert_ne!(fd, -1);
            Fd::from_raw(fd)
        };

        let waker_fd = unsafe {
            let efd = libc::eventfd(0, 0);
            assert_ne!(efd, -1);
            Fd::from_raw(efd)
        };

        let im = Self { fd, waker_fd };

        im.register(&im.waker_fd);

        im
    }

    pub(crate) fn register(&self, fd: &Fd) {
        unsafe {
            let mut ev = libc::epoll_event {
                events: libc::EPOLLIN as _,
                u64: fd.as_raw() as _,
            };
            let r = libc::epoll_ctl(self.fd.as_raw(), libc::EPOLL_CTL_ADD, fd.as_raw(), &mut ev);
            assert_ne!(r, -1);
        }
    }

    pub(crate) fn wait(&self, events: &mut Vec<libc::epoll_event>, timeout: Option<Duration>) {
        unsafe {
            let n = libc::epoll_wait(
                self.fd.as_raw(),
                events.as_mut_ptr(),
                events.capacity() as _,
                timeout
                    .map(|tot| tot.as_millis() as ffi::c_int)
                    .unwrap_or(-1),
            );
            if n < 1 {
                events.clear();
            } else {
                events.set_len(n as _);
            }
        }
    }

    pub fn wake(&self) {
        unsafe {
            let u: u64 = 1;
            let r = libc::write(
                self.waker_fd.as_raw(),
                &u as *const _ as _,
                mem::size_of_val(&u),
            );
            assert_ne!(r, -1);
        }
    }

    pub(crate) fn clear_waker(&self) {
        unsafe {
            let mut u: u64 = 0;
            libc::read(
                self.waker_fd.as_raw(),
                &mut u as *mut _ as _,
                mem::size_of_val(&u),
            );
        }
    }
}