Skip to main content

xen/evtchn/
mod.rs

1mod port;
2use std::{
3    os::fd::{AsFd, AsRawFd, BorrowedFd, RawFd},
4    rc::Rc,
5};
6
7use xen_sys::{xenevtchn_close, xenevtchn_fd, xenevtchn_handle, xenevtchn_open, xentoollog_logger};
8
9pub use self::port::XenEventChannelPort;
10use crate::XenError;
11
12#[derive(Debug, Clone)]
13pub struct XenEventChannel(pub(crate) Rc<*mut xenevtchn_handle>);
14
15impl XenEventChannel {
16    pub fn new() -> Result<Self, XenError> {
17        Self::new_with_options(None, 0)
18    }
19
20    pub fn new_with_options(
21        logger: Option<&mut xentoollog_logger>,
22        flags: u32,
23    ) -> Result<Self, XenError> {
24        let handle = unsafe {
25            xenevtchn_open(
26                logger.map_or_else(std::ptr::null_mut, |p| p as *mut _),
27                flags,
28            )
29        };
30
31        if handle.is_null() {
32            return Err(XenError::Other("Failed to open Xen event channel"));
33        }
34
35        Ok(Self(Rc::new(handle)))
36    }
37}
38
39impl Drop for XenEventChannel {
40    fn drop(&mut self) {
41        tracing::trace!("closing Xen event channel");
42        unsafe {
43            xenevtchn_close(*self.0);
44        }
45    }
46}
47
48impl AsFd for XenEventChannel {
49    fn as_fd(&self) -> BorrowedFd<'_> {
50        unsafe { BorrowedFd::borrow_raw(self.as_raw_fd()) }
51    }
52}
53
54impl AsRawFd for XenEventChannel {
55    fn as_raw_fd(&self) -> RawFd {
56        unsafe { xenevtchn_fd(*self.0) }
57    }
58}