lockfree_object_pool/
spin_lock_reusable.rs

1use crate::spin_lock_object_pool::SpinLockObjectPool;
2use std::mem::ManuallyDrop;
3use std::ops::{Deref, DerefMut};
4
5/// Wrapper over T used by [`SpinLockObjectPool`].
6///
7/// Access is allowed with [`std::ops::Deref`] or [`std::ops::DerefMut`]
8/// # Example
9/// ```rust
10///  use lockfree_object_pool::SpinLockObjectPool;
11///
12///  let pool = SpinLockObjectPool::<u32>::new(
13///    ||  Default::default(),
14///    |v| {
15///      *v = 0;
16///    }
17///  );
18///  let mut item = pool.pull();
19///
20///  *item = 5;
21///  let work = *item * 5;
22/// ```
23pub struct SpinLockReusable<'a, T> {
24    pool: &'a SpinLockObjectPool<T>,
25    data: ManuallyDrop<T>,
26}
27
28impl<'a, T> SpinLockReusable<'a, T> {
29    /// Create new element
30    ///
31    /// # Arguments
32    /// * `pool` object pool owner
33    /// * `data` element to wrappe
34    #[inline]
35    pub fn new(pool: &'a SpinLockObjectPool<T>, data: ManuallyDrop<T>) -> Self {
36        Self { pool, data }
37    }
38}
39
40impl<'a, T> DerefMut for SpinLockReusable<'a, T> {
41    #[inline]
42    fn deref_mut(&mut self) -> &mut Self::Target {
43        &mut self.data
44    }
45}
46
47impl<'a, T> Deref for SpinLockReusable<'a, T> {
48    type Target = T;
49
50    #[inline]
51    fn deref(&self) -> &Self::Target {
52        &self.data
53    }
54}
55
56impl<'a, T> Drop for SpinLockReusable<'a, T> {
57    #[inline]
58    fn drop(&mut self) {
59        let data = unsafe {
60            // SAFETY: self.data is never referenced again and it isn't dropped
61            ManuallyDrop::take(&mut self.data)
62        };
63        self.pool.attach(data);
64    }
65}