A reader report records shared-read coordination. This program takes a selected number of RwLock read guards, probes try_write, and reports the shared-read status.

Program

Play the program to choose how many readers hold the lock and watch the write probe and status change.

readers
rwlock_read_coordination_report.rs
Replay: real traced execution (multi-file project)
use std::sync::RwLock;

fn main() {
    let readers = 2;
    let lock = RwLock::new(7);
    let mut guards = Vec::new();
    for _ in 0..readers {
        if let Ok(guard) = lock.try_read() {
            guards.push(guard);
        }
    }
    let active = guards.len();
    let write_blocked = lock.try_write().is_err();
    let status = if active == 0 {
        "writable"
    } else if active == 1 {
        "single"
    } else {
        "shared"
    };
    println!("readers={active} write_blocked={write_blocked} {status}");
}
use std::sync::RwLock;

fn main() {
    let readers = 0;
    let lock = RwLock::new(7);
    let mut guards = Vec::new();
    for _ in 0..readers {
        if let Ok(guard) = lock.try_read() {
            guards.push(guard);
        }
    }
    let active = guards.len();
    let write_blocked = lock.try_write().is_err();
    let status = if active == 0 {
        "writable"
    } else if active == 1 {
        "single"
    } else {
        "shared"
    };
    println!("readers={active} write_blocked={write_blocked} {status}");
}
use std::sync::RwLock;

fn main() {
    let readers = 1;
    let lock = RwLock::new(7);
    let mut guards = Vec::new();
    for _ in 0..readers {
        if let Ok(guard) = lock.try_read() {
            guards.push(guard);
        }
    }
    let active = guards.len();
    let write_blocked = lock.try_write().is_err();
    let status = if active == 0 {
        "writable"
    } else if active == 1 {
        "single"
    } else {
        "shared"
    };
    println!("readers={active} write_blocked={write_blocked} {status}");
}
  1. readers ← 2, lock ← RwLock { data: 7, poisoned: false, .. }, guards ← []

    3fn main() {4    let reader→ 2s = 2; //@readers=2, 0, 15    let loc→ RwLock { data: 7, poisoned: false, .. }k = RwLock::new(7);6    let mut guard→ []s = Vec::new();7    for _ in 0..readers {
  2. for _ in 0..readers

    pass 1 of 2
    6let mut guards = Vec::new();7for _ in 0..reader2s {8    if let Ok(guard) = lock.try_read() {
  3. for _ in 0..readers

    pass 2 of 2
    6let mut guards = Vec::new();7for _ in 0..reader2s {8    if let Ok(guard) = lock.try_read() {
  4. active ← 2, write_blocked ← true, status ← "shared"

    11    }12    let activ→ 2e = guards.len();13    let write_blocke→ trued = lock.try_write().is_err();14    let statu→ "shared"s = if activ2e == 0 {15        "writable"16    } else if activ2e == 1 {17        "single"18    } else {19        "shared"20    };21    println!("readers={active} write_blocked={write_blocked} {status}");22}
    outputreaders=2 write_blocked=true shared
  1. readers ← 0, lock ← RwLock { data: 7, poisoned: false, .. }, guards ← []

    3fn main() {4    let reader→ 0s = 0;5    let loc→ RwLock { data: 7, poisoned: false, .. }k = RwLock::new(7);6    let mut guard→ []s = Vec::new();7    for _ in 0..readers {8        if let Ok(guard) = lock.try_read() {9            guards.push(guard);10        }11    }12    let activ→ 0e = guards.len();13    let write_blocke→ falsed = lock.try_write().is_err();14    let statu→ "writable"s = if activ0e == 0 {15        "writable"16    } else if activ0e == 1 {17        "single"18    } else {19        "shared"20    };21    println!("readers={active} write_blocked={write_blocked} {status}");22}
    outputreaders=0 write_blocked=false writable
  1. readers ← 1, lock ← RwLock { data: 7, poisoned: false, .. }, guards ← []

    3fn main() {4    let reader→ 1s = 1;5    let loc→ RwLock { data: 7, poisoned: false, .. }k = RwLock::new(7);6    let mut guard→ []s = Vec::new();7    for _ in 0..readers {
  2. for _ in 0..readers

    6let mut guards = Vec::new();7for _ in 0..reader1s {8    if let Ok(guard) = lock.try_read() {
  3. active ← 1, write_blocked ← true, status ← "single"

    11    }12    let activ→ 1e = guards.len();13    let write_blocke→ trued = lock.try_write().is_err();14    let statu→ "single"s = if activ1e == 0 {15        "writable"16    } else if activ1e == 1 {17        "single"18    } else {19        "shared"20    };21    println!("readers={active} write_blocked={write_blocked} {status}");22}
    outputreaders=1 write_blocked=true single
shared reads `RwLock::try_read` grants multiple read guards at once, so several readers can observe the value together.
write exclusion `try_write` is rejected while any read guard is held, so the report shows the write as blocked.
reader count The number of live read guards drives the coordination status from writable through shared.