use crate::bindings as C;
use crate::device::Device;
use crate::error::create_resource;
use std::io;
use std::ptr::NonNull;
use std::sync::Arc;
#[derive(Clone)]
pub struct Context(Arc<Owner>);
impl Context {
pub(crate) fn ffi_ptr(&self) -> *mut C::ibv_context {
self.0.ffi_ptr()
}
#[inline]
pub fn open(device: &Device) -> io::Result<Self> {
let owner = unsafe {
let ctx = create_resource(
|| C::ibv_open_device(device.ffi_ptr()),
|| "failed to open device",
)?;
Arc::new(Owner { ctx })
};
Ok(Self(owner))
}
}
struct Owner {
ctx: NonNull<C::ibv_context>,
}
unsafe impl Send for Owner {}
unsafe impl Sync for Owner {}
impl Owner {
fn ffi_ptr(&self) -> *mut C::ibv_context {
self.ctx.as_ptr()
}
}
impl Drop for Owner {
fn drop(&mut self) {
unsafe {
let context = self.ffi_ptr();
let ret = C::ibv_close_device(context);
assert_eq!(ret, 0);
}
}
}