[][src]Crate triple_buffer

Triple buffering in Rust

In this crate, we propose a Rust implementation of triple buffering. This is a non-blocking thread synchronization mechanism that can be used when a single producer thread is frequently updating a shared data block, and a single consumer thread wants to be able to read the latest available version of the shared data whenever it feels like it.

Examples

For many use cases, you can use the default interface, designed for maximal ergonomics and synchronization performance, which is based on moving values into the buffer and subsequently accessing them via shared references:

// Create a triple buffer
use triple_buffer::TripleBuffer;
let buf = TripleBuffer::new(0);

// Split it into an input and output interface, to be respectively sent to
// the producer thread and the consumer thread
let (mut buf_input, mut buf_output) = buf.split();

// The producer can move a value into the buffer at any time
buf_input.write(42);

// The consumer can access the latest value from the producer at any time
let latest_value_ref = buf_output.read();
assert_eq!(*latest_value_ref, 42);

In situations where moving the original value away and being unable to modify it after the fact is too costly, such as if creating a new value involves dynamic memory allocation, you can opt into the lower-level "raw" interface, which allows you to access the buffer's data in place and precisely control when updates are propagated.

This data access method is more error-prone and comes at a small performance cost, which is why you will need to enable it explicitly using the "raw" cargo feature.

// Create and split a triple buffer
use triple_buffer::TripleBuffer;
let buf = TripleBuffer::new(String::with_capacity(42));
let (mut buf_input, mut buf_output) = buf.split();

// Mutate the input buffer in place
{
    // Acquire a reference to the input buffer
    let raw_input = buf_input.raw_input_buffer();

    // In general, you don't know what's inside of the buffer, so you should
    // always reset the value before use (this is a type-specific process).
    raw_input.clear();

    // Perform an in-place update
    raw_input.push_str("Hello, ");
}

// Publish the input buffer update
buf_input.raw_publish();

// Manually fetch the buffer update from the consumer interface
buf_output.raw_update();

// Acquire a mutable reference to the output buffer
let raw_output = buf_output.raw_output_buffer();

// Post-process the output value before use
raw_output.push_str("world!");

Structs

Input

Producer interface to the triple buffer

Output

Consumer interface to the triple buffer

TripleBuffer

A triple buffer, useful for nonblocking and thread-safe data sharing