How to understand the description of the panic of the method 'read' of RwLock in docs?

This can be a newbie question. According to doc's description, function 'read' might panic when called if the lock is already held by the current thread.
Here is the code, it won't panic:

use std::sync::{ RwLock };

fn main() {
    let locked = RwLock::new(0);
    let locked_c = RwLock::read(&locked); // here, has main thread already acquired the lock? Or, only method 'write' will hold the lock?
    let locked_t = RwLock::read(&locked);
    println!("{:?}", *locked_c.unwrap());
    println!("{:?}", *locked_t.unwrap());
}

BTW, here is the same description of Mutex's method 'lock'.Here is the code, but it will panic:

use std::sync::{ Mutex };

fn main() {
    let locked = Mutex::new(0);
    let locked_c = Mutex::lock(&locked);
    let locked_t = Mutex::lock(&locked);
    println!("{:?}", *locked_c.unwrap());
    println!("{:?}", *locked_t.unwrap());
}

I'm confused about this:

  1. Will method 'read' of RwLock hold the lock?
  2. Why won't multiple reads of RwLock in one thread panic?

Of course. It wouldn't be possible to make it sound otherwise – if reading doesn't hold the lock, then how would writing even know when reading is finished?

Because "may panic" is not "will panic". Locking from the same thread is an error, so you must not do it either way.

Synchronization primitives in the std::sync actually are built on top of the platform native ones. Some platform may panic on such cases while others may not. But why it may panic on such cases? Because it's one of the common source of deadlocks. For example, this code deadlocks.

use std::sync::RwLock;
use std::thread;
use std::time::Duration;

static LOCK: RwLock<i32> = RwLock::new(42);

fn main() {
    let r1 = LOCK.read().unwrap();
    thread::spawn(|| {
        let w1 = LOCK.write().unwrap();
    });
    // to ensure write lock is touched by the thread above
    thread::sleep(Duration::from_millis(100));
    let r2 = LOCK.read().unwrap();

    println!("Done!");
}

Thanks for your kind reply. Is it possible for you to provide the "will panic" code? I'm not clear about under what circumstances "read“ or "lock" will panic. The second snippet seems not panic, it is 'timeout'.

It's possible for some code to, say, panic on Windows and deadlock on Linux (or vice-versa). So the "will panic" might be impossible in general.

So, for deadlock, some platforms will panic, some will just like 'timeout'. Can i take it that way?

"Timeout" is the behavior of playground, which just puts a hard cap on the execution time for every request. In real system, it will just hang until some external signal changes the situation (most likely by killing the process).

1 Like

Got it, really appreciate your help.

No, by definition. If the documentation merely says that it may panic, then I can't come up with code that will definitely panic.

This topic was automatically closed 90 days after the last reply. We invite you to open a new topic if you have further questions or comments.