pub struct ContextCell<T> { /* private fields */ }Expand description
A thread-local cell storing a raw pointer to the current wide event.
This type provides safe methods for setting, getting, and saving/restoring the pointer, which is used by the generated guard to manage nested scopes.
§Safety Invariants
The raw pointer stored in this cell is sound because:
- The guard owns the event. The
WideEvent<K>is a field of the guard, which is on the stack (or in thescope()future’s state). The guard outlives any code that callscurrent()within the same scope. - Set on creation, cleared on drop. The guard’s
newsets the pointer; itsDroprestores the previous pointer (or null) before the innerScopedGuard::Dropruns. - Nested scopes save/restore the previous pointer via
replaceand theprev_ptrfield on the guard. - No cross-thread access.
thread_local!means each thread has its own cell. For async,tokio::task_local!moves with the task across threads.
The &'static lifetime returned by accessors is a “valid for the duration
of the guard” lifetime — the standard pattern used by thread_local
accessors (e.g., tracing’s Span::current()).
§Why UnsafeCell instead of Cell?
ContextCell needs to be Sync (so a static reference to it is
usable from any thread, with the pointer contents thread-local via
thread_local! mechanics). Cell<T> is !Sync. UnsafeCell<T> is
Sync for any T (including raw pointers).
Internally we use UnsafeCell<*mut T> so the cell is Sync without
needing an unsafe impl Sync shim, and the Stacked Borrows model
under miri doesn’t see the cell’s get as a “shared” access that
would conflict with a later &mut deref of the stored pointer.