use crate::{error::Result, try_seal};
use std::{
ffi::c_void,
ptr::null_mut,
sync::atomic::{AtomicPtr, Ordering},
};
use crate::bindgen;
#[derive(Debug)]
pub struct MemoryPool {
pub(crate) handle: AtomicPtr<c_void>,
}
impl MemoryPool {
pub fn new() -> Result<Self> {
let mut handle: *mut c_void = null_mut();
let clear_on_destruction = true;
try_seal!(unsafe { bindgen::MemoryPoolHandle_New(clear_on_destruction, &mut handle) })?;
Ok(MemoryPool {
handle: AtomicPtr::new(handle),
})
}
pub fn pool_count(&self) -> Result<u64> {
let mut count: u64 = 0;
try_seal!(unsafe { bindgen::MemoryPoolHandle_PoolCount(self.get_handle(), &mut count) })?;
Ok(count)
}
pub fn pool_allocated_byte_count(&self) -> Result<u64> {
let mut count: u64 = 0;
try_seal!(unsafe {
bindgen::MemoryPoolHandle_AllocByteCount(self.get_handle(), &mut count)
})?;
Ok(count)
}
pub fn pool_used_byte_count(&self) -> Result<i64> {
let mut count: i64 = 0;
try_seal!(unsafe { bindgen::MemoryPoolHandle_UseCount(self.get_handle(), &mut count) })?;
Ok(count)
}
pub fn is_initialized(&self) -> Result<bool> {
let mut result: bool = false;
try_seal!(unsafe {
bindgen::MemoryPoolHandle_IsInitialized(self.get_handle(), &mut result)
})?;
Ok(result)
}
pub(crate) unsafe fn get_handle(&self) -> *mut c_void {
self.handle.load(Ordering::SeqCst)
}
}
impl Drop for MemoryPool {
fn drop(&mut self) {
if let Err(err) = try_seal!(unsafe { bindgen::MemoryPoolHandle_Destroy(self.get_handle()) })
{
panic!("Failed to destroy memory pool: {:?}", err);
}
}
}
#[cfg(test)]
mod tests {
use crate::*;
#[test]
fn can_create_and_destroy_memory_pool() {
let memory_pool = MemoryPool::new().unwrap();
assert!(memory_pool.is_initialized().unwrap());
std::mem::drop(memory_pool);
}
#[test]
fn can_get_pool_count() {
let memory_pool = MemoryPool::new().unwrap();
let count = memory_pool.pool_count().unwrap();
let is_initialized = memory_pool.is_initialized().unwrap();
assert_eq!(count, 0);
assert!(is_initialized);
}
}