276. AtomicBool::swap — Let Exactly One Thread Claim the Job
“Check the flag, then set it” has a gap where two threads both see false — and your run-once code runs twice. swap sets and reads the flag in one atomic step.
Say only one thread should print a deprecation warning, spawn the background worker, or run cleanup. The obvious flag check is broken:
| |
Same check-then-act race as yesterday’s fetch_max story: two threads load false, both pass the if, both warn. The fix is again a single atomic call:
| |
swap stores the new value and returns the previous one as a single atomic operation. Only the first caller gets false back — everyone else sees true and skips the block. No mutex, no window to slip through:
| |
Relaxed is fine while the flag itself is the only shared state. The moment the winning thread writes data that losers will read, you need Acquire/Release ordering — or just reach for OnceLock, which handles that (and blocking until init finishes) for you.
Where swap beats Once/OnceLock: it produces no value, it never blocks the losers, and you can re-arm it — store(false, ...) resets the flag for the next round. Think “claim ticket”, not “lazy init”.
Works on every Atomic* type, stable since Rust 1.0.