Crate sync_cow

Source
Expand description

Thread-safe clone-on-write container with lock-less reading

The SyncCow is a container for concurrent writing and reading of data. It’s intended to be a faster alternative to std::sync::RwLock. Especially scenarios with many concurrent readers heavily benefit from the SyncCow. Reading is guaranteed to be lock-less and return immediately. Writing is only blocked by other write-accesses, never by any read-access. A SyncCow with only one writer and arbitrary readers will never block. As SyncCow stores two copies of it’s contained value and read values are handed out as std::sync::Arc, a program using SyncCow might have a higher memory-footprint compared to std::sync::RwLock.

Note that readers might read outdated data when using the SyncCow, as writing and reading concurrently is possible. If that is indesireable consider std::sync::RwLock.

Usage is similar to RwLock, but writing to the container is done through edit and a closure instead of acquiring a write-lock:

use sync_cow::SyncCow;
use std::sync::Arc;
use std::any::Any;

fn main() -> Result<(),Box<dyn Any + Send>> {
    let cow = Arc::new(SyncCow::new(5));

    // Arc is only needed to pass the ref to the threads
    let cow_write_arc = cow.clone();
    let cow_read_arc = cow.clone();

    let writer = std::thread::spawn(move || {
        let cow = &*cow_write_arc; // unpack immediately to avoid Arc deref
        let mut val = 0;
        cow.edit(|x| {
            val = *x;
            *x = 4;
        });
        println!("Cow was {} when writing", val);
    });

    let reader = std::thread::spawn(move || {
        let cow = &*cow_read_arc; // unpack immediately to avoid Arc deref
        println!("Cow was {} when reading", cow.read());
    });

    writer.join()?;
    reader.join()?;
    Ok(())
}

Structs§

SyncCow
Thread-safe clone-on-write container with lock-less reading.