lockout-hazard
Lock-free hazard pointers for safe memory reclamation in concurrent Rust data structures.
Why hazard pointers?
When one thread unlinks a node from a lock-free structure, other threads may still hold transient references to that node. Freeing immediately can cause use-after-free. Hazard pointers solve this by:
- Letting readers publish protected pointers in hazard slots.
- Deferring reclamation of retired nodes until no hazard slot references them.
Usage
use ;
use Ordering;
static DOMAIN: Domain = new;
let shared = from_box;
let guard = DOMAIN.protect.unwrap;
assert_eq!;
// Replace and retire old pointer.
shared
.swap
.retire;
guard.clear;
DOMAIN.collect;
// Final cleanup of current pointer.
shared
.swap
.retire;
DOMAIN.collect;
Core types
Domain— owns hazard slots and retired-node reclamation.AtomicPtr<T>— managed atomic pointer wrapper that returnsReplaced<T>from mutation ops.Guard<'_, T>— protected reference preventing reclamation while held.Replaced<T>— displaced pointer token that must be retired (or intentionally forgotten).
Reclamation model
- Retired pointers are pushed to a lock-free retired stack.
collect()snapshots active hazards and frees only unprotected retired pointers.- Automatic collection is triggered periodically (default threshold: 8 retires).
Safety requirements
For Domain::retire_ptr::<T>(ptr) / Replaced::retire:
- Pointer must no longer be reachable from shared atomics.
- Pointer must originate from
Box. - Pointer must not be retired more than once.