pub struct RetireNode {
ptr: *mut (),
retire_fn: Box<dyn Fn(*mut ())>,
}
impl RetireNode {
pub fn new(ptr: *mut (), func: Box<dyn Fn(*mut ())>) -> Self {
Self {
ptr,
retire_fn: func,
}
}
pub fn const_ptr(&self) -> *const () {
self.ptr as *const ()
}
pub unsafe fn retire(self) {
let retire_fn = self.retire_fn;
retire_fn(self.ptr);
}
}
#[cfg(test)]
mod tests {
use std::sync::{atomic, Arc};
use super::*;
#[test]
fn new_node() {
RetireNode::new(std::ptr::null_mut(), Box::new(|_| {}));
}
#[test]
fn get_ptr() {
let node = RetireNode::new(0x123 as *mut (), Box::new(|_| {}));
assert_eq!(0x123 as *const (), node.const_ptr());
}
#[test]
fn retire_node() {
let retired_ptr = Arc::new(atomic::AtomicPtr::new(std::ptr::null_mut()));
let node_retire_target = retired_ptr.clone();
let node = RetireNode::new(
0x123 as *mut (),
Box::new(move |ptr| {
node_retire_target.store(ptr, atomic::Ordering::SeqCst);
}),
);
assert_eq!(
std::ptr::null_mut(),
retired_ptr.load(atomic::Ordering::SeqCst)
);
unsafe { node.retire() };
assert_eq!(0x123 as *mut (), retired_ptr.load(atomic::Ordering::SeqCst));
}
}