remem-ai 0.6.88

Local-first coding agent memory for Claude Code and OpenAI Codex
Documentation
use std::marker::PhantomData;
use std::rc::Rc;
use std::sync::{Condvar, Mutex};
use std::thread::ThreadId;

#[derive(Debug)]
pub(crate) struct EnvLockError;

impl std::fmt::Display for EnvLockError {
    fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
        f.write_str("environment lock failed")
    }
}

impl std::error::Error for EnvLockError {}

#[derive(Debug)]
struct EnvLockState {
    owner: Option<ThreadId>,
    depth: usize,
}

pub(crate) struct EnvLock {
    state: Mutex<EnvLockState>,
    available: Condvar,
}

pub(crate) struct EnvGuard {
    lock: &'static EnvLock,
    _not_send: PhantomData<Rc<()>>,
}

impl EnvLock {
    pub(crate) const fn new() -> Self {
        Self {
            state: Mutex::new(EnvLockState {
                owner: None,
                depth: 0,
            }),
            available: Condvar::new(),
        }
    }

    pub(crate) fn lock(&'static self) -> Result<EnvGuard, EnvLockError> {
        let current = std::thread::current().id();
        let mut state = self
            .state
            .lock()
            .unwrap_or_else(|poisoned| poisoned.into_inner());
        loop {
            match state.owner {
                None => {
                    state.owner = Some(current);
                    state.depth = 1;
                    return Ok(EnvGuard {
                        lock: self,
                        _not_send: PhantomData,
                    });
                }
                Some(owner) if owner == current => {
                    state.depth += 1;
                    return Ok(EnvGuard {
                        lock: self,
                        _not_send: PhantomData,
                    });
                }
                Some(_) => {
                    state = self
                        .available
                        .wait(state)
                        .unwrap_or_else(|poisoned| poisoned.into_inner());
                }
            }
        }
    }
}

impl Drop for EnvGuard {
    fn drop(&mut self) {
        let current = std::thread::current().id();
        let mut state = self
            .lock
            .state
            .lock()
            .unwrap_or_else(|poisoned| poisoned.into_inner());
        debug_assert_eq!(state.owner, Some(current));
        state.depth = state.depth.saturating_sub(1);
        if state.depth == 0 {
            state.owner = None;
            self.lock.available.notify_all();
        }
    }
}