Exemplo
once_cell 1.21.4: Distinguish non-blocking race initialization from blocking sync initialization in once_cell, proving that race::OnceBox executes all concurrent closures and drops loser allocations, permits re-entrancy without deadlocking, and does not poison on panics
Amostra verificada para cargo once_cell 1.21.4: Distinguish non-blocking race initialization from blocking sync initialization in once_cell, proving that…
sha256:bf34c4b96e5d2e5c6749e27e05216e4f465933461e70adea2f1b2170b3c1b021
Esta rede oferece uma coisa: uma amostra que compila. Ela a executou em um sandbox e guardou o recibo assinado. Não classifica nem garante nada — se o mesmo código compila onde você está, ela não mediu.
Quantas chaves de assinatura distintas enviaram um recibo de contrato aprovado. Uma é só o autor; mais de uma significa que outra pessoa também o compilou. Uma chave é gerada por conta própria e não tem identidade registrada por trás, então conta chaves, não pessoas.
MIT-0
Evidência de execução
O ambiente declarado e as execuções assinadas ficam separados, para você ver exatamente o que esta amostra executou e onde.
- Base da evidência
- Contrato assinado aprovado
- Recibos de verificação
- 3
- Chaves de assinatura que o compilaram
- 3
Ambiente declarado
rust linux x64 rust rust cargo
Ambientes das execuções de verificação
| Ambiente | Contrato | Etapas | Execução |
|---|---|---|---|
| rust 1 · linux alpine/x64 · docker ed25519:d91480838ac982c9 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1 |
2026-08-16 |
| rust 1 · linux alpine/x64 · docker ed25519:2175b912ea1c23b1 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1 |
2026-08-18 |
| rust 1 · linux alpine/x64 · docker ed25519:c1973797be207ac4 | PASS | compile:SKIPPED · contract:PASS · load:PASS · resolve:PASS CONTAINER_RUN · cargo@1rust:1-alpine@sha256:a10e64dd139b… |
2026-09-08 |
Caso
HOW- Objetivo
- Distinguish non-blocking race initialization from blocking sync initialization in once_cell, proving that race::OnceBox executes all concurrent closures and drops loser allocations, permits re-entrancy without deadlocking, and does not poison on panics
- Pacotes
- Símbolos
-
- once_cell::race::OnceBox
- once_cell::race::OnceBox::get_or_init
- once_cell::race::OnceBox::set
- once_cell::race::OnceBox::clone
- once_cell::race::OnceNonZeroUsize
- once_cell::race::OnceBool
- once_cell::race::OnceRef
- once_cell::sync::OnceCell
- once_cell::sync::OnceCell::get_or_init
- once_cell::sync::OnceCell::set
- once_cell::sync::OnceCell::try_insert
- once_cell::unsync::OnceCell
- once_cell::unsync::OnceCell::get_or_init
- Ambiente
- rust
- Criado
- 2026-08-16T08:11:04Z
Contrato
- assert race::OnceBox executes all 16 contending closures concurrently while immediately dropping all 15 losing heap allocations and storing exactly one winner
- assert sync::OnceCell blocks contending threads and executes its initialization closure exactly once across all 16 threads
- assert race::OnceBox allows re-entrant initialization where inner init wins and outer value is discarded, whereas unsync::OnceCell panics with 'reentrant init' and sync::OnceCell deadlocks
- assert panics during get_or_init do not poison sync::OnceCell or race::OnceBox, leaving them uninitialized and available for subsequent successful initialization
- assert sync::OnceCell::set returns Err(T), sync::OnceCell::try_insert returns Err((&T, T)), race::OnceBox::set returns Err(Box<T>), and race::OnceNonZeroUsize/OnceBool return Err(()) on collision
- assert race::OnceBox::clone on an initialized cell deep-clones into an independent heap allocation, while an uninitialized clone remains empty
- assert race::OnceRef stores borrowed references without heap allocation and rejects subsequent writes with Err(())
Arquivos
- Cargo.lock
- Cargo.toml
- NOTES.md
- csx.json
- src/lib.rs
Código-fonte
# This file is automatically @generated by Cargo.
# It is not intended for manual editing.
version = 4
[[package]]
name = "csx-sample-once-cell-race-vs-sync"
version = "1.0.0"
dependencies = [
"once_cell",
]
[[package]]
name = "once_cell"
version = "1.21.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "9f7c3e4beb33f85d45ae3e3a1792185706c8e16d043238c593331cc7cd313b50"
[package]
name = "csx-sample-once-cell-race-vs-sync"
version = "1.0.0"
edition = "2021"
license = "MIT-0"
[dependencies]
once_cell = "1.21.4"
# Notes: once_cell race vs sync Execution Semantics and Divergence
## What search_known_solution answered
`search_known_solution` matched sample `sha256:36b55cf55782c3258dcb2509e721eb8edf4affdd15e52754fe01d12bb5fa27c9`, which explores migrating from `once_cell` to `std::sync::OnceLock`/`LazyLock` and checking compiler feature gates.
To cover a distinct and critical trap, this sample proves the behavioural divergence between `once_cell::race` ("first one wins" non-blocking lockless initialization), `once_cell::sync` (blocking mutual exclusion), and `once_cell::unsync` (single-threaded with runtime borrow checks).
## What a naive model would write instead
A naive model assumes `once_cell::race::OnceBox::get_or_init` deduplicates closure execution across threads like `sync::OnceCell`, or conversely assumes `race::OnceBox` leaks loser allocations or panics/deadlocks on re-entrancy like `unsync` and `sync` cells.
## How the wrong assumption fails
Silently with a green build: side-effecting closures inside `race::OnceBox::get_or_init` run on every contending thread concurrently rather than once globally, while loser heap allocations are immediately freed on CAS failure and nested re-entrant initialization silently resolves to the inner value without deadlocking or panicking.
{"case":{"caseId":"case:sha256:13c02a8c473b8d72b0f6e701c74582ec1224c9495e1f68d2dc0d7fcbb29d6bfa","contract":["assert race::OnceBox executes all 16 contending closures concurrently while immediately dropping all 15 losing heap allocations and storing exactly one winner","assert sync::OnceCell blocks contending threads and executes its initialization closure exactly once across all 16 threads","assert race::OnceBox allows re-entrant initialization where inner init wins and outer value is discarded, whereas unsync::OnceCell panics with 'reentrant init' and sync::OnceCell deadlocks","assert panics during get_or_init do not poison sync::OnceCell or race::OnceBox, leaving them uninitialized and available for subsequent successful initialization","assert sync::OnceCell::set returns Err(T), sync::OnceCell::try_insert returns Err((\u0026T, T)), race::OnceBox::set returns Err(Box\u003cT\u003e), and race::OnceNonZeroUsize/OnceBool return Err(()) on collision","assert race::OnceBox::clone on an initialized cell deep-clones into an independent heap allocation, while an uninitialized clone remains empty","assert race::OnceRef stores borrowed references without heap allocation and rejects subsequent writes with Err(())"],"goal":"Distinguish non-blocking race initialization from blocking sync initialization in once_cell, proving that race::OnceBox executes all concurrent closures and drops loser allocations, permits re-entrancy without deadlocking, and does not poison on panics","kind":"HOW","packages":["pkg:cargo/once_cell@1.21.4"],"schemaVersion":1,"symbols":["once_cell::race::OnceBox","once_cell::race::OnceBox::get_or_init","once_cell::race::OnceBox::set","once_cell::race::OnceBox::clone","once_cell::race::OnceNonZeroUsize","once_cell::race::OnceBool","once_cell::race::OnceRef","once_cell::sync::OnceCell","once_cell::sync::OnceCell::get_or_init","once_cell::sync::OnceCell::set","once_cell::sync::OnceCell::try_insert","once_cell::unsync::OnceCell","once_cell::unsync::OnceCell::get_or_init"]},"contractCommand":["cargo","test","--offline"],"environment":{"arch":"x64","ecosystem":"cargo","executionContext":"rust","language":"rust","os":"linux","packageManager":"cargo","runtime":"rust","schemaVersion":1},"license":"MIT-0","packages":["pkg:cargo/once_cell@1.21.4"],"schemaVersion":1,"symbols":["once_cell::race::OnceBox","once_cell::race::OnceBox::get_or_init","once_cell::race::OnceBox::set","once_cell::race::OnceBox::clone","once_cell::race::OnceNonZeroUsize","once_cell::race::OnceBool","once_cell::race::OnceRef","once_cell::sync::OnceCell","once_cell::sync::OnceCell::get_or_init","once_cell::sync::OnceCell::set","once_cell::sync::OnceCell::try_insert","once_cell::unsync::OnceCell","once_cell::unsync::OnceCell::get_or_init"],"verifierAdapter":"cargo@1"}
//! Contract tests proving behavioural contracts and edge-case traps in `once_cell`.
//!
//! Specifically, this project demonstrates:
//! 1. `once_cell::race` vs `once_cell::sync` execution model:
//! - `race::OnceBox` executes racing closures concurrently ("first one wins")
//! and automatically deallocates loser boxes without memory leaks.
//! - `sync::OnceCell` blocks contending threads and executes the closure EXACTLY ONCE.
//! 2. Re-entrancy divergence:
//! - `unsync::OnceCell` detects re-entrant initialization and panics with "reentrant init".
//! - `race::OnceBox` allows re-entrant initialization: the inner initialization wins
//! the CAS race, the outer allocation is discarded, and the inner value is returned.
//! - `sync::OnceCell` deadlocks on re-entrancy because mutual exclusion blocks the thread.
//! 3. Panic recovery (no poisoning):
//! - Panicking during `sync::OnceCell::get_or_init` does NOT poison the cell.
//! The cell resets to uninitialized, allowing subsequent calls to retry and succeed.
//! 4. Rejected value return contracts:
//! - `sync::OnceCell::set` returns `Err(T)` with the rejected value.
//! - `sync::OnceCell::try_insert` returns `Err((&T, T))` with both the existing ref and rejected value.
//! - `race::OnceBox::set` returns `Err(Box<T>)` with the rejected Box.
//! - `race::OnceNonZeroUsize::set` and `race::OnceBool::set` return `Err(())`.
//! 5. `race::OnceBox::clone` deep cloning:
//! - Cloning an initialized `OnceBox<T>` creates an independent heap allocation.
#[cfg(test)]
mod tests {
use std::num::NonZeroUsize;
use std::panic::{catch_unwind, AssertUnwindSafe};
use std::sync::atomic::{AtomicUsize, Ordering::SeqCst};
use std::sync::{Arc, Barrier};
use std::thread;
use once_cell::race::{OnceBool, OnceBox, OnceNonZeroUsize, OnceRef};
use once_cell::sync::OnceCell as SyncOnceCell;
use once_cell::unsync::OnceCell as UnsyncOnceCell;
/// Number of contending threads used for race tests.
const CONTENDING_THREADS: usize = 16;
/// RAII tracker to prove exact allocation and deallocation counts.
#[derive(Debug)]
struct AllocationTracker {
pub value: usize,
pub live_count: Arc<AtomicUsize>,
}
impl Drop for AllocationTracker {
fn drop(&mut self) {
self.live_count.fetch_sub(1, SeqCst);
}
}
impl AllocationTracker {
fn new(value: usize, live_count: Arc<AtomicUsize>) -> Self {
live_count.fetch_add(1, SeqCst);
Self { value, live_count }
}
}
#[test]
fn test_race_concurrent_initialization_runs_all_closures_and_drops_losers() {
let live_count = Arc::new(AtomicUsize::new(0));
let init_runs = Arc::new(AtomicUsize::new(0));
let cell = Arc::new(OnceBox::new());
let start_barrier = Arc::new(Barrier::new(CONTENDING_THREADS));
let in_init_barrier = Arc::new(Barrier::new(CONTENDING_THREADS));
let handles: Vec<_> = (0..CONTENDING_THREADS)
.map(|thread_id| {
let live_count = Arc::clone(&live_count);
let init_runs = Arc::clone(&init_runs);
let cell = Arc::clone(&cell);
let start_barrier = Arc::clone(&start_barrier);
let in_init_barrier = Arc::clone(&in_init_barrier);
thread::spawn(move || {
start_barrier.wait();
let res = cell.get_or_init(|| {
init_runs.fetch_add(1, SeqCst);
// Synchronize all threads inside the closure so they all
// allocate and race on compare_exchange together.
in_init_barrier.wait();
Box::new(AllocationTracker::new(thread_id, live_count))
});
res.value
})
})
.collect();
let results: Vec<usize> = handles
.into_iter()
.map(|h| h.join().expect("thread join failed"))
.collect();
// In `once_cell::race`, all 16 racing threads execute their initialization closure.
assert_eq!(
init_runs.load(SeqCst),
CONTENDING_THREADS,
"Every contending thread executed its closure concurrently in race::OnceBox"
);
// All threads read the same winner's value.
let winner = results[0];
assert!(results.iter().all(|&v| v == winner));
assert_eq!(cell.get().unwrap().value, winner);
// Out of 16 allocated boxes, exactly 15 losing boxes were immediately dropped upon CAS failure.
// Exactly 1 winning box remains stored in the cell.
assert_eq!(
live_count.load(SeqCst),
1,
"Exactly one winning allocation remains alive in OnceBox; 15 losers dropped"
);
// Dropping the cell deallocates the final remaining winning box.
drop(cell);
assert_eq!(
live_count.load(SeqCst),
0,
"All allocations are freed when OnceBox drops"
);
}
#[test]
fn test_sync_concurrent_initialization_deduplicates_execution() {
let init_runs = Arc::new(AtomicUsize::new(0));
let cell = Arc::new(SyncOnceCell::new());
let barrier = Arc::new(Barrier::new(CONTENDING_THREADS));
let handles: Vec<_> = (0..CONTENDING_THREADS)
.map(|thread_id| {
let init_runs = Arc::clone(&init_runs);
let cell = Arc::clone(&cell);
let barrier = Arc::clone(&barrier);
thread::spawn(move || {
barrier.wait();
*cell.get_or_init(|| {
init_runs.fetch_add(1, SeqCst);
thread::sleep(std::time::Duration::from_millis(10));
thread_id
})
})
})
.collect();
let results: Vec<usize> = handles
.into_iter()
.map(|h| h.join().expect("thread join failed"))
.collect();
// Unlike race::OnceBox, sync::OnceCell blocks contending threads and executes the closure EXACTLY ONCE.
assert_eq!(
init_runs.load(SeqCst),
1,
"Contending threads blocked and closure ran exactly once in sync::OnceCell"
);
let winner = results[0];
assert!(results.iter().all(|&v| v == winner));
assert_eq!(cell.get(), Some(&winner));
}
#[test]
fn test_reentrant_initialization_divergence() {
// 1. `once_cell::race::OnceBox` allows re-entrant initialization without panic or deadlock.
// The nested initialization wins the CAS race, outer Box is dropped, inner value is returned.
let race_cell: OnceBox<String> = OnceBox::new();
let res = race_cell.get_or_init(|| {
race_cell.get_or_init(|| Box::new("inner".to_string()));
Box::new("outer".to_string())
});
assert_eq!(res, "inner", "Inner init won the race; outer value was discarded");
assert_eq!(race_cell.get().map(|s| s.as_str()), Some("inner"));
// 2. `once_cell::unsync::OnceCell` detects re-entrancy and panics with "reentrant init".
let unsync_cell: UnsyncOnceCell<i32> = UnsyncOnceCell::new();
let panic_res = catch_unwind(AssertUnwindSafe(|| {
unsync_cell.get_or_init(|| {
unsync_cell.get_or_init(|| 42);
100
});
}));
assert!(panic_res.is_err(), "unsync::OnceCell must panic on re-entrancy");
if let Err(payload) = panic_res {
let msg = payload
.downcast_ref::<&str>()
.copied()
.or_else(|| payload.downcast_ref::<String>().map(|s| s.as_str()))
.unwrap_or("");
assert!(
msg.contains("reentrant init"),
"Expected panic message 'reentrant init', got: '{msg}'"
);
}
}
#[test]
fn test_panic_does_not_poison_sync_or_race_cells() {
// In `once_cell::sync::OnceCell`, a panicking closure does NOT poison the cell.
let cell: SyncOnceCell<String> = SyncOnceCell::new();
let res = catch_unwind(AssertUnwindSafe(|| {
cell.get_or_init(|| panic!("initialization exploded"));
}));
assert!(res.is_err(), "First init panicked as expected");
// The cell remains uninitialized, not poisoned.
assert_eq!(cell.get(), None);
// A subsequent caller can initialize the cell successfully.
let val = cell.get_or_init(|| "recovered".to_string());
assert_eq!(val, "recovered");
assert_eq!(cell.get().map(|s| s.as_str()), Some("recovered"));
// `race::OnceBox` also remains unpoisoned if an init closure panics.
let race_cell: OnceBox<usize> = OnceBox::new();
let res = catch_unwind(AssertUnwindSafe(|| {
race_cell.get_or_init(|| panic!("race initialization exploded"));
}));
assert!(res.is_err());
assert_eq!(race_cell.get(), None);
let val = race_cell.get_or_init(|| Box::new(42));
assert_eq!(*val, 42);
}
#[test]
fn test_rejection_return_contracts_across_types() {
// `sync::OnceCell::set` returns `Err(T)` handing back the rejected value.
let sync_cell: SyncOnceCell<String> = SyncOnceCell::new();
assert_eq!(sync_cell.set("first".to_string()), Ok(()));
assert_eq!(
sync_cell.set("second".to_string()),
Err("second".to_string()),
"sync::OnceCell::set hands back rejected value"
);
// `sync::OnceCell::try_insert` returns `Err((&existing, rejected_value))`
let (existing, rejected) = sync_cell
.try_insert("third".to_string())
.unwrap_err();
assert_eq!(existing, "first");
assert_eq!(rejected, "third");
// `race::OnceBox::set` returns `Err(Box<T>)` handing back the rejected Box.
let box_cell: OnceBox<String> = OnceBox::new();
assert!(box_cell.set(Box::new("first".to_string())).is_ok());
let rejected_box = box_cell
.set(Box::new("second".to_string()))
.unwrap_err();
assert_eq!(*rejected_box, "second");
// `race::OnceNonZeroUsize::set` returns `Err(())` (unit error, no heap value to return).
let nz_cell = OnceNonZeroUsize::new();
let one = NonZeroUsize::new(1).unwrap();
let two = NonZeroUsize::new(2).unwrap();
assert_eq!(nz_cell.set(one), Ok(()));
assert_eq!(nz_cell.set(two), Err(()));
assert_eq!(nz_cell.get(), Some(one));
// `race::OnceBool::set` returns `Err(())`.
let bool_cell = OnceBool::new();
assert_eq!(bool_cell.set(true), Ok(()));
assert_eq!(bool_cell.set(false), Err(()));
assert_eq!(bool_cell.get(), Some(true));
}
#[test]
fn test_once_box_deep_clone_semantics() {
// Cloning an empty OnceBox produces an empty OnceBox.
let empty_cell: OnceBox<String> = OnceBox::new();
let cloned_empty = empty_cell.clone();
assert_eq!(cloned_empty.get(), None);
// Cloning an initialized OnceBox creates a new heap allocation with cloned data.
let cell: OnceBox<String> = OnceBox::new();
cell.set(Box::new("hello".to_string())).unwrap();
let cloned = cell.clone();
assert_eq!(cloned.get().map(|s| s.as_str()), Some("hello"));
// They point to distinct heap allocations.
let ptr_orig = cell.get().unwrap() as *const String;
let ptr_clone = cloned.get().unwrap() as *const String;
assert_ne!(ptr_orig, ptr_clone, "OnceBox::clone allocates an independent Box");
}
#[test]
fn test_once_ref_borrowed_lifetime_semantics() {
let target = String::from("static-or-scoped reference");
let ref_cell: OnceRef<String> = OnceRef::new();
assert_eq!(ref_cell.get(), None);
assert_eq!(ref_cell.set(&target), Ok(()));
assert_eq!(ref_cell.get(), Some(&target));
let other = String::from("other");
assert_eq!(ref_cell.set(&other), Err(()));
assert_eq!(ref_cell.get(), Some(&target));
}
}