Merge pull request #928 from dhardy/libc
Make libc dependency optional
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 57bb361..3ec7462 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -12,6 +12,10 @@
### Fixes
- The `Bernoulli` distribution constructors now reports an error on NaN and on
`denominator == 0`. (#925)
+- Use `std::sync::Once` to register fork handler, avoiding possible atomicity violation (#928)
+
+### Changes
+- Unix: make libc dependency optional; only use fork protection with std feature (#928)
### Additions
- Implement `std::error::Error` for `BernoulliError` (#919)
diff --git a/Cargo.toml b/Cargo.toml
index e6af38d..03d5e35 100644
--- a/Cargo.toml
+++ b/Cargo.toml
@@ -27,7 +27,7 @@
serde1 = [] # does nothing, deprecated
# Optional dependencies:
-std = ["rand_core/std", "rand_chacha/std", "alloc", "getrandom"]
+std = ["rand_core/std", "rand_chacha/std", "alloc", "getrandom", "libc"]
alloc = ["rand_core/alloc"] # enables Vec and Box support (without std)
# re-export optional WASM dependencies to avoid breakage:
# Warning: wasm-bindgen and stdweb features will be removed in rand 0.8;
@@ -68,7 +68,7 @@
[target.'cfg(unix)'.dependencies]
# Used for fork protection (reseeding.rs)
-libc = { version = "0.2.22", default-features = false }
+libc = { version = "0.2.22", optional = true, default-features = false }
# Emscripten does not support 128-bit integers, which are used by ChaCha code.
# We work around this by using a different RNG.
diff --git a/src/rngs/adapter/reseeding.rs b/src/rngs/adapter/reseeding.rs
index f7a694f..5460e34 100644
--- a/src/rngs/adapter/reseeding.rs
+++ b/src/rngs/adapter/reseeding.rs
@@ -279,11 +279,10 @@
}
-#[cfg(all(unix, not(target_os = "emscripten")))]
+#[cfg(all(unix, feature = "std", not(target_os = "emscripten")))]
mod fork {
- use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
- #[allow(deprecated)] // Required for compatibility with Rust < 1.24.
- use core::sync::atomic::{ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT};
+ use core::sync::atomic::{AtomicUsize, Ordering};
+ use std::sync::Once;
// Fork protection
//
@@ -297,16 +296,12 @@
// don't update `fork_counter`, so a reseed is attempted as soon as
// possible.
- #[allow(deprecated)]
- static RESEEDING_RNG_FORK_COUNTER: AtomicUsize = ATOMIC_USIZE_INIT;
+ static RESEEDING_RNG_FORK_COUNTER: AtomicUsize = AtomicUsize::new(0);
pub fn get_fork_counter() -> usize {
RESEEDING_RNG_FORK_COUNTER.load(Ordering::Relaxed)
}
- #[allow(deprecated)]
- static FORK_HANDLER_REGISTERED: AtomicBool = ATOMIC_BOOL_INIT;
-
extern "C" fn fork_handler() {
// Note: fetch_add is defined to wrap on overflow
// (which is what we want).
@@ -314,14 +309,14 @@
}
pub fn register_fork_handler() {
- if !FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) {
- unsafe { libc::pthread_atfork(None, None, Some(fork_handler)) };
- FORK_HANDLER_REGISTERED.store(true, Ordering::Relaxed);
- }
+ static REGISTER: Once = Once::new();
+ REGISTER.call_once(|| unsafe {
+ libc::pthread_atfork(None, None, Some(fork_handler));
+ });
}
}
-#[cfg(not(all(unix, not(target_os = "emscripten"))))]
+#[cfg(not(all(unix, feature = "std", not(target_os = "emscripten"))))]
mod fork {
pub fn get_fork_counter() -> usize {
0