Amanieu / parking_lot

Compact and efficient synchronization primitives for Rust. Also provides an API for creating custom synchronization primitives.
Apache License 2.0
2.77k stars 217 forks source link

Fail to upgrade a upgradable read lock twice in a scope #392

Closed ling7334 closed 1 year ago

ling7334 commented 1 year ago

Enviroument

>>Get-ComputerInfo

WindowsBuildLabEx                                       : 22621.1.amd64fre.ni_release.220506-1250
WindowsCurrentVersion                                   : 6.3
WindowsEditionId                                        : Professional
WindowsInstallationType                                 : Client
WindowsProductName                                      : Windows 10 Pro
WindowsVersion                                          : 2009
OSDisplayVersion                                        : 22H2

>> cargo --version
cargo 1.69.0 (6e9a83356 2023-04-12)
#Cargo.toml
[package]
name = "singleflight"
version = "0.1.0"
edition = "2021"
publish = false

[dependencies]
parking_lot = "0.12"
tracing = { version="0.1", features=["log"] }

[dev-dependencies]
tracing-test = "0.2"

Problem

Try to call with_upgraded of RwLockUpgradableReadGuard twice in a single scope, but stuck on trying to aquire the lock on the second call. Example on rust playground

Here is a minimal problem reproduce

use parking_lot::RwLock;
struct Lock(RwLock<i32>);
fn main() {
    let lock = Lock(RwLock::new(0));
    let mut rl = lock.0.upgradable_read();
    rl.with_upgraded(|_| {
        println!("lock upgrade");
    });
    rl.with_upgraded(|_| {
        println!("lock upgrade");
    });
}

but success to aquire lock seperately like below

fn test_rwlock() {
    use parking_lot::RwLock;
    struct Lock(RwLock<i32>);
    let lock = Lock(RwLock::new(0));
    let rl = lock.0.read();
    drop(rl);
    let wl = lock.0.write();
    trace!("lock upgrade");
    drop(wl);
    let wl = lock.0.write();
    trace!("lock upgrade");
    drop(wl);
}

Expectation

upgradable read lock rl can be access after with_upgraded was called, or can anyone confirm it is by design.