cycle_ptr 0.1.0

Smart pointers, with cycles
//! Implement the read and write locks on generation.
#[cfg(not(feature = "single_generation_mt"))]
use super::TaskExclusion;
use super::{MTControlBlock, MTGeneration, ObjectsLink};
use crate::list::List;
use crate::util::NonNull;
use std::sync::RwLockReadGuard;
#[cfg(not(feature = "single_generation_mt"))]
use std::sync::{MutexGuard, RwLockWriteGuard};

/// A shared lock on a generation.
///
/// Prevents objects in the generation from changing membership.
pub(crate) struct MTGenerationReadLock<'a> {
    /// Raw pointer to the generation, needed to implement [MTGenerationReadLock::same_generation].
    raw_generation_ptr: NonNull<MTGeneration>,
    /// Objects contained in this generation.
    _objects: RwLockReadGuard<'a, List<MTControlBlock, ObjectsLink>>,
}

/// An exclusive lock on a generation.
///
/// Prevents objects in the generation from changing membership and prevents the garbage collector from running.
#[cfg(not(feature = "single_generation_mt"))]
pub(crate) struct MTGenerationWriteLock<'a> {
    /// Task exclusion lock, to prevent the garbage collector from running.
    _task_exclusion_lock: MutexGuard<'a, TaskExclusion>,
    /// Objects contained in this generation.
    pub(super) objects: RwLockWriteGuard<'a, List<MTControlBlock, ObjectsLink>>,
}

impl<'a> MTGenerationReadLock<'a> {
    /// Instantiate a lock.
    #[allow(
        clippy::missing_const_for_fn,
        reason = "You can't create these in a const context anyway."
    )]
    #[inline]
    pub(super) fn new(
        raw_generation_ptr: NonNull<MTGeneration>,
        objects: RwLockReadGuard<'a, List<MTControlBlock, ObjectsLink>>,
    ) -> Self {
        MTGenerationReadLock {
            raw_generation_ptr,
            _objects: objects,
        }
    }

    /// Test if this lock locks the specified generation.
    #[inline]
    pub(crate) fn same_generation(&self, other: &MTGeneration) -> bool {
        self.raw_generation_ptr == NonNull::from_ref(other)
    }
}

#[cfg(not(feature = "single_generation_mt"))]
impl<'a> MTGenerationWriteLock<'a> {
    /// Instantiate a lock.
    #[allow(
        clippy::missing_const_for_fn,
        reason = "You can't create these in a const context anyway."
    )]
    #[inline]
    pub(super) fn new(
        task_exclusion_lock: MutexGuard<'a, TaskExclusion>,
        objects: RwLockWriteGuard<'a, List<MTControlBlock, ObjectsLink>>,
    ) -> Self {
        MTGenerationWriteLock {
            _task_exclusion_lock: task_exclusion_lock,
            objects,
        }
    }
}