use crate::error_utilities::{log_last_os_err, log_ret_last_os_err};
use crate::Context;
use rdma_sys::{ibv_comp_channel, ibv_create_comp_channel, ibv_destroy_comp_channel};
use std::os::unix::prelude::{AsRawFd, RawFd};
use std::{io, ptr::NonNull, sync::Arc};
use tokio::io::unix::AsyncFd;
#[derive(Debug)]
pub(crate) struct EventChannel {
_ctx: Arc<Context>,
inner_ec: NonNull<ibv_comp_channel>,
}
impl EventChannel {
pub(crate) fn as_ptr(&self) -> *mut ibv_comp_channel {
self.inner_ec.as_ptr()
}
pub(crate) fn new(ctx: Arc<Context>) -> io::Result<Self> {
let inner_ec = NonNull::new(unsafe { ibv_create_comp_channel(ctx.as_ptr()) })
.ok_or_else(log_ret_last_os_err)?;
Ok(Self {
_ctx: ctx,
inner_ec,
})
}
pub(crate) fn async_fd(&self) -> io::Result<AsyncFd<RawFd>> {
AsyncFd::new(unsafe { *self.as_ptr() }.fd.as_raw_fd())
}
}
unsafe impl Sync for EventChannel {}
unsafe impl Send for EventChannel {}
impl Drop for EventChannel {
fn drop(&mut self) {
let errno = unsafe { ibv_destroy_comp_channel(self.as_ptr()) };
if errno != 0_i32 {
log_last_os_err();
}
}
}