|
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); |
|
} |
|
} |
|
} |
In function register_fork_handler:
- load and check the atomic variable FORK_HANDLER_REGISTERED.
- if not, call the C library function.
- set the atomic variable so that the next call of the same function will not execute the C library function again.
It seems to me that atomic FORK_HANDLER_REGISTERED is utilized to guarantee that libc::pthread_at_fork is only called once.
However, if the function is called by two threads, a possible atomicity violation may happen:
- Th1: load and check
- Th2: load and check; call C function; set the value
- Th1: call C function again
The fix is simple: use one compare_and_swap() to replace the two separate atomic load and store.
rand/src/rngs/adapter/reseeding.rs
Lines 303 to 309 in 885655d
In function register_fork_handler:
It seems to me that atomic FORK_HANDLER_REGISTERED is utilized to guarantee that libc::pthread_at_fork is only called once.
However, if the function is called by two threads, a possible atomicity violation may happen:
The fix is simple: use one compare_and_swap() to replace the two separate atomic load and store.