use super::*;
use std::{pin, ptr};
pub trait Aio {
fn aio(&self) -> &NngAio;
fn aio_mut(&mut self) -> &mut NngAio;
}
#[derive(Debug)]
pub struct NngAio {
aio: *mut nng_aio,
}
unsafe impl Send for NngAio {}
pub type AioArg<T> = pin::Pin<Box<T>>;
pub type AioArgPtr = *mut ::std::os::raw::c_void;
pub type AioCallback = unsafe extern "C" fn(arg1: AioArgPtr);
impl NngAio {
pub fn create<T, F>(func: F, callback: AioCallback) -> Result<AioArg<T>>
where
T: Aio,
F: FnOnce(NngAio) -> T,
{
let mut aio: *mut nng_aio = ptr::null_mut();
let aio_wrapper = Self { aio };
let mut aio_arg = Box::new(func(aio_wrapper));
let aio_arg_ptr = aio_arg.as_mut() as *mut _ as AioArgPtr;
let res = unsafe { nng_aio_alloc(&mut aio, Some(callback), aio_arg_ptr) };
nng_int_to_result(res)?;
aio_arg.aio_mut().aio = aio;
Ok(pin::Pin::from(aio_arg))
}
pub unsafe fn nng_aio(&self) -> *mut nng_aio {
debug_assert!(!self.aio.is_null(), "nng_aio null");
self.aio
}
pub unsafe fn set_iov(&self, iov: &[nng_iov]) -> Result<()> {
let res = nng_aio_set_iov(self.nng_aio(), iov.len() as u32, iov.as_ptr());
nng_int_to_result(res)
}
pub unsafe fn aio_count(&self) -> usize {
nng_aio_count(self.nng_aio())
}
pub unsafe fn get_output(&self, index: u32) -> *mut ::std::os::raw::c_void {
nng_aio_get_output(self.nng_aio(), index)
}
pub unsafe fn cancel(&self) {
nng_aio_cancel(self.nng_aio())
}
pub unsafe fn abort_i32(&self, err: i32) {
nng_aio_abort(self.nng_aio(), err)
}
pub unsafe fn wait(&self) {
nng_aio_wait(self.nng_aio())
}
pub unsafe fn result(&self) -> Result<()> {
let res = nng_aio_result(self.nng_aio());
nng_int_to_result(res)
}
pub fn set_timeout(&self, timeout: nng_duration) {
unsafe {
nng_aio_set_timeout(self.nng_aio(), timeout);
}
}
}
impl Drop for NngAio {
fn drop(&mut self) {
unsafe {
if !self.aio.is_null() {
trace!("NngAio.drop {:x}", self.aio as u64);
nng_aio_free(self.aio);
}
}
}
}