Rollup merge of #82596 - matklad:rwlock, r=sfackler

clarify RW lock's priority gotcha

In particular, the following program works on Linux, but deadlocks on
mac:

```rust
    use std::{
        sync::{Arc, RwLock},
        thread,
        time::Duration,
    };

    fn main() {
        let lock = Arc::new(RwLock::new(()));

        let r1 = thread::spawn({
            let lock = Arc::clone(&lock);
            move || {
                let _rg = lock.read();
                eprintln!("r1/1");
                sleep(1000);

                let _rg = lock.read();
                eprintln!("r1/2");

                sleep(5000);
            }
        });
        sleep(100);
        let w = thread::spawn({
            let lock = Arc::clone(&lock);
            move || {
                let _wg = lock.write();
                eprintln!("w");
            }
        });
        sleep(100);
        let r2 = thread::spawn({
            let lock = Arc::clone(&lock);
            move || {
                let _rg = lock.read();
                eprintln!("r2");
                sleep(2000);
            }
        });

        r1.join().unwrap();
        r2.join().unwrap();
        w.join().unwrap();
    }

    fn sleep(ms: u64) {
        std:🧵:sleep(Duration::from_millis(ms))
    }
```

Context: I was completely mystified by a my CI deadlocking on mac ([here](https://github.com/matklad/xshell/pull/7)), until ``@azdavis`` debugged the issue. See a stand-alone reproduciton here: https://github.com/matklad/xshell/pull/15
This commit is contained in:
Dylan DPC 2021-02-27 21:56:24 +01:00 committed by GitHub
commit e38b3eb0b5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23

View File

@ -23,7 +23,9 @@ use crate::sys_common::rwlock as sys;
///
/// The priority policy of the lock is dependent on the underlying operating
/// system's implementation, and this type does not guarantee that any
/// particular policy will be used.
/// particular policy will be used. In particular, a writer which is waiting to
/// acquire the lock in `write` might or might not block concurrent calls to
/// `read`.
///
/// The type parameter `T` represents the data that this lock protects. It is
/// required that `T` satisfies [`Send`] to be shared across threads and