From 8550a5af45bd31b4ab7f3a6b7910af28c19913ac Mon Sep 17 00:00:00 2001 From: Mechiel Lukkien Date: Thu, 7 Mar 2024 10:05:35 +0100 Subject: [PATCH] don't expose functions on the prng that aren't mutex-protected the current Intn calls in queue could be called concurrently, found by the race detector with upcoming new tests. best to just prevent any possible concurrent access. --- mox-/rand.go | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/mox-/rand.go b/mox-/rand.go index 2881f68..3aac6d7 100644 --- a/mox-/rand.go +++ b/mox-/rand.go @@ -9,20 +9,32 @@ import ( ) type rand struct { - *mathrand.Rand + rand *mathrand.Rand sync.Mutex } -// NewPseudoRand returns a new PRNG seeded with random bytes from crypto/rand. +// NewPseudoRand returns a new PRNG seeded with random bytes from crypto/rand. Its +// functions can be called concurrently. func NewPseudoRand() *rand { - return &rand{Rand: mathrand.New(mathrand.NewSource(CryptoRandInt()))} + return &rand{rand: mathrand.New(mathrand.NewSource(CryptoRandInt()))} +} + +func (r *rand) Float64() float64 { + r.Lock() + defer r.Unlock() + return r.rand.Float64() +} + +func (r *rand) Intn(n int) int { + r.Lock() + defer r.Unlock() + return r.rand.Intn(n) } -// Read can be called concurrently. func (r *rand) Read(buf []byte) (int, error) { r.Lock() defer r.Unlock() - return r.Rand.Read(buf) + return r.rand.Read(buf) } // CryptoRandInt returns a cryptographically random number.