[draft] investigate solutions to immediate-reseeding-on-fork #1377
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This is an investigation branch into potential solutions to #1362.
No fork protection
The simplest solution is simply to choose not provide fork protection.
GlobalRng
ThreadRng
has thread-local state which cannot be reached byfork_handler
. The simplest "solution" to this is to replace thread-local state with global state that can be, henceGlobalRng
using aMutex
.Perf. on a single thread is (unsurprisingly) fine, however holding onto a
GlobalRng
reference could easily cause dead-locking, makingfn global_rng() -> GlobalRng
a hazard.Obviously this is not a good solution where high-performance generation is needed from multiple threads; in this case users would need to seed and store local generators. This is possibly the best option in such a case anyway.
Implication:
global_rng
is fine for occasional usage and/or in single-thread environments, but probably we would want to encourage users to construct a local RNG for any significant usage.An additional advantage of replacing
ThreadRng
with this is less thread-local state usage.Frequent polling of RESEEDING_RNG_FORK_COUNTER
The current fork handler works by checking
RESEEDING_RNG_FORK_COUNTER
only when generating a new block of random state. We could check this much more often (on every value generation), but this likely would have a large perf. hit.Other solutions?
There are various approaches to fast thread-safe containers and consensus algorithms. We could possibly attempt to design an RNG along such lines, however this would be far from a trivial undertaking (especially reviewing for security) and still likely to severely under-perform existing RNGs.
Maybe there are other existing solutions we're overlooking?