rslock icon indicating copy to clipboard operation
rslock copied to clipboard

Lock Guard Drop for `tokio-comp`

Open theBeardA opened this issue 9 months ago • 1 comments

I was implementing my own lock manager when i came across this library. since my code base is based on tokio and I dont want to bring in async-std, I was wondering if Drop implementation for the tokio-comp feature using conditional compile is the way to go? I might be missing something, but from my initial experiments, this approach appears to work for Drop.​

#[cfg(feature = "tokio-comp")]
impl Drop for LockGuard {
    fn drop(&mut self) {
        let lock = self.lock.clone();
        let lock_manager = self.lock.lock_manager.clone();
        tokio::spawn(async move {
            let _ = lock_manager.unlock(&lock).await;
        });
    }
}

theBeardA avatar Mar 07 '25 07:03 theBeardA

rslock >0.7.0 intends for you to explicitly handle drop by calling unlock. Doing otherwise could lead to race conditions.

let lock = lock_manager.lock(key, ttl).await?;
// do work
lock_manager.unlock(&lock).await; // Explicit unlock

See https://github.com/hexcowboy/rslock/blob/d84f38f8036cb245946f19dc23e82bb50e84e61c/src/lock.rs#L397-L407

If you really want to implement manual dropping without unlock(), you could do something like this

pub struct AutoUnlockGuard {
    lock: Lock,
    released: bool,
}

impl AutoUnlockGuard {
    pub fn new(lock: Lock) -> Self {
        Self {
            lock,
            released: false,
        }
    }

    pub async fn release(&mut self) {
        if !self.released {
            self.released = true;
            self.lock.lock_manager.unlock(&self.lock).await;
        }
    }
}

impl Drop for AutoUnlockGuard {
    fn drop(&mut self) {
        if !self.released {
            log::warn!("AutoUnlockGuard dropped without explicit release");
        }
    }
}

hexcowboy avatar Mar 28 '25 19:03 hexcowboy