rustlockingmutexborrow-checkerrwlock

Create MappedRwLockWriteGuard from a reference in if/else in Rust


I am trying to use parking_lot to write a block of code where I am using the property of a RwLock whenever I don't already have a reference to it:

let property = if i_already_have_the_reference {
  simple_mut_reference_to_property
} else {
  my_lock.write().map(|v| v.property)
};

However, this doesn't work since the first branch is a simple &mut MyReference type, and the second branch is a MappedRwLockWriteGuard.

If I dereference MappedRwLockWriteGuard with &mut, the compiler will drop the temporary at the end of the else branch.

So, the only solution I can think of is to create a dummy MappedRwLockWriteGuard from simple_mut_reference_to_property, which doesn't actually unlock a lock on the drop.

What is your suggestion to fix this problem?

If impossible, is there an API that allows manual lock/unlocking of the C-way?

P.S: the reason I use parking_lot instead of std::sync is that I thought I can fix the issue with .map


Solution

  • A useful pattern in cases like that is to have a variable that is sometimes initialized and sometimes not. You can hold the lock in that variable:

    let mut write_guard;
    let property = if i_already_have_the_reference {
        simple_mut_reference_to_property
    } else {
        write_guard = my_lock.write();
        &mut write_guard.property
    };