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}