-
-
Notifications
You must be signed in to change notification settings - Fork 473
Description
The ReseedingRng claims to protect against fork:
rand/src/rngs/adapter/reseeding.rs
Lines 292 to 302 in ef89cbe
// Fork protection | |
// | |
// We implement fork protection on Unix using `pthread_atfork`. | |
// When the process is forked, we increment `RESEEDING_RNG_FORK_COUNTER`. | |
// Every `ReseedingRng` stores the last known value of the static in | |
// `fork_counter`. If the cached `fork_counter` is less than | |
// `RESEEDING_RNG_FORK_COUNTER`, it is time to reseed this RNG. | |
// | |
// If reseeding fails, we don't deal with this by setting a delay, but just | |
// don't update `fork_counter`, so a reseed is attempted as soon as | |
// possible. |
Here's an example that shows that after fork
, the parent and all child processes will still have the same state for the thread rng: https://play.rust-lang.org/?version=stable&mode=debug&edition=2021&gist=f63e9a09df0ec7f67d84dacb6d39ac32, which produces output like:
parent (pid 11): random::<u64>(): 0x2fe7d602f7aba388
parent (pid 11): spawned child 0 (pid 27)
parent (pid 11): spawned child 1 (pid 28)
parent (pid 11): spawned child 2 (pid 29)
parent (pid 11): spawned child 3 (pid 30)
child 3 (pid 30): random::<u64>(): 0x2907c1d06b61f595
parent (pid 11): spawned child 4 (pid 31)
parent (pid 11): finished spawning 5 child procs
child 4 (pid 31): random::<u64>(): 0x2907c1d06b61f595
parent (pid 11): random::<u64>(): 0x2907c1d06b61f595
child 2 (pid 29): random::<u64>(): 0x2907c1d06b61f595
child 1 (pid 28): random::<u64>(): 0x2907c1d06b61f595
child 0 (pid 27): random::<u64>(): 0x2907c1d06b61f595
I haven't dug deeply into why what you do currently is wrong, but it causes very tough to track-down bugs. CC @joshlf, who filed #1169, leading to the current design of the fork handling.
Background / why I'm stuck with fork: I have code that runs as a Postgres extension (https://github.com/pgcentralfoundation/pgrx), and PG will will run some init code in the parent, but most code runs in a child process (forked per-connection). Both used the uuid
crate, which (apparently -- some dep in our tree seems to have turned it on) has a fastrand
feature for using the rand
crate. At the moment we've avoided use of uuids in that code (it didn't actually need them), but if rand
is going to try to handle this at all, it might as well be right.