// A "once" is a relatively simple primitive, and it's also typically provided // by the OS as well (see `pthread_once` or `InitOnceExecuteOnce`). The OS // primitives, however, tend to have surprising restrictions, such as the Unix // one doesn't allow an argument to be passed to the function. // // As a result, we end up implementing it ourselves in the standard library. // This also gives us the opportunity to optimize the implementation a bit which // should help the fast path on call sites. // // So to recap, the guarantees of a Once are that it will call the // initialization closure at most once, and it will never return until the one // that's running has finished running. This means that we need some form of // blocking here while the custom callback is running at the very least. // Additionally, we add on the restriction of **poisoning**. Whenever an // initialization closure panics, the Once enters a "poisoned" state which means // that all future calls will immediately panic as well. // // So to implement this, one might first reach for a `Mutex`, but those cannot // be put into a `static`. It also gets a lot harder with poisoning to figure // out when the mutex needs to be deallocated because it's not after the closure // finishes, but after the first successful closure finishes. // // All in all, this is instead implemented with atomics and lock-free // operations! Whee! cfg_if::cfg_if! { if #[cfg(any( target_os = "linux", target_os = "android", all(target_arch = "wasm32", target_feature = "atomics"), target_os = "freebsd", target_os = "openbsd", target_os = "dragonfly", target_os = "fuchsia", target_os = "hermit", ))] { mod futex; pub use futex::{Once, OnceState}; } else { mod generic; pub use generic::{Once, OnceState}; } }