Skip to content

Commit ae3a416

Browse files
committed
Fix #911: use Once instead of AtomicBool
1 parent a67173e commit ae3a416

File tree

2 files changed

+8
-9
lines changed

2 files changed

+8
-9
lines changed

CHANGELOG.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ You may also find the [Upgrade Guide](https://rust-random.github.io/book/update.
1212
### Fixes
1313
- The `Bernoulli` distribution constructors now reports an error on NaN and on
1414
`denominator == 0`. (#925)
15+
- Use `std::sync::Once` to register fork handler, avoiding possible atomicity violation (#928)
1516

1617
### Changes
1718
- Unix: make libc dependency optional; only use fork protection with std feature (#928)

src/rngs/adapter/reseeding.rs

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -281,9 +281,10 @@ where
281281

282282
#[cfg(all(unix, feature = "std", not(target_os = "emscripten")))]
283283
mod fork {
284-
use core::sync::atomic::{AtomicBool, AtomicUsize, Ordering};
284+
use core::sync::atomic::{AtomicUsize, Ordering};
285285
#[allow(deprecated)] // Required for compatibility with Rust < 1.24.
286-
use core::sync::atomic::{ATOMIC_BOOL_INIT, ATOMIC_USIZE_INIT};
286+
use core::sync::atomic::{ATOMIC_USIZE_INIT};
287+
use std::sync::Once;
287288

288289
// Fork protection
289290
//
@@ -304,20 +305,17 @@ mod fork {
304305
RESEEDING_RNG_FORK_COUNTER.load(Ordering::Relaxed)
305306
}
306307

307-
#[allow(deprecated)]
308-
static FORK_HANDLER_REGISTERED: AtomicBool = ATOMIC_BOOL_INIT;
309-
310308
extern "C" fn fork_handler() {
311309
// Note: fetch_add is defined to wrap on overflow
312310
// (which is what we want).
313311
RESEEDING_RNG_FORK_COUNTER.fetch_add(1, Ordering::Relaxed);
314312
}
315313

316314
pub fn register_fork_handler() {
317-
if !FORK_HANDLER_REGISTERED.load(Ordering::Relaxed) {
318-
unsafe { libc::pthread_atfork(None, None, Some(fork_handler)) };
319-
FORK_HANDLER_REGISTERED.store(true, Ordering::Relaxed);
320-
}
315+
static REGISTER: Once = Once::new();
316+
REGISTER.call_once(|| unsafe {
317+
libc::pthread_atfork(None, None, Some(fork_handler));
318+
});
321319
}
322320
}
323321

0 commit comments

Comments
 (0)