#lock-free #atomic #container #lazy #deref

freezebox

FreezeBox: a deref’able lazy-initialized container

5 releases

0.2.3 Jun 21, 2022
0.2.2 Feb 1, 2022
0.2.1 Aug 3, 2020
0.1.1 Aug 3, 2020

#100 in Concurrency

Download history 20/week @ 2022-03-16 11/week @ 2022-03-23 1/week @ 2022-04-06 25/week @ 2022-04-27 17/week @ 2022-05-04 61/week @ 2022-05-11 17/week @ 2022-05-18 18/week @ 2022-05-25 37/week @ 2022-06-01 9/week @ 2022-06-08 13/week @ 2022-06-15 14/week @ 2022-06-22

73 downloads per month

MIT license

15KB
137 lines

Rust FreezeBox: a deref'able lazy-initialized container.

FreezeBox<T> is a container that can have two possible states:

  • uninitialized: deref is not allowed.
  • initialized: deref to a &T is possible.

To upgrade a FreezeBox to the initialized state, call lazy_init. lazy_init does not require a mutable reference, making FreezeBox suitable for sharing objects first and initializing them later.

Attempting to lazy_init more than once, or deref while uninitialized will cause a panic.

FreezeBox is compatible with no_std projects (no feature flags needed). It may be used in any environment with a memory allocator.

FreezeBox uses unsafe code internally. To ensure soundness, the unit tests pass under Miri, and the unsafe code is simple and easy to understand.

The minimum supported Rust version is 1.48.

Examples

This example creates a shared data structure, then circles back to initialize one member.

use freezebox::FreezeBox;
use std::sync::Arc;

/// A data structure that we will initialize lazily.
#[derive(Default)]
struct Resources {
    name: FreezeBox<String>
}

// Create an instance of the `Resources` struct, which contains an
// uninitialized `name` field.
let resources = Arc::new(Resources::default());

// Clone the Arc to emulate sharing with other threads, contexts,
// or data structures.
let res2 = resources.clone();

// Here we emulate another thread accessing the shared data structure.
// NOTE: it's still our responsibility to ensure that the FreezeBox
// is initialized before anyone dereferences it.
//
let func = move || {
    // explicit deref
    assert_eq!(*res2.name, "Hello!");
    // implicit deref allows transparent access to inner methods
    assert_eq!(res2.name.len(), 6);
};

resources.name.lazy_init("Hello!".to_string());
func();

Not quite what you were looking for?

There are many similar crates out there:

No runtime deps