Merge pull request #13332 from LK4D4/fix_race_in_rand
Use goroutine-safe version of rand.Source
This commit is contained in:
commit
0b092ef5cf
4 changed files with 64 additions and 6 deletions
|
@ -3,7 +3,8 @@ package namesgenerator
|
|||
import (
|
||||
"fmt"
|
||||
"math/rand"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/random"
|
||||
)
|
||||
|
||||
var (
|
||||
|
@ -309,7 +310,7 @@ var (
|
|||
"yonath",
|
||||
}
|
||||
|
||||
rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
|
||||
rnd = rand.New(random.NewSource())
|
||||
)
|
||||
|
||||
func GetRandomName(retry int) string {
|
||||
|
|
34
random/random.go
Normal file
34
random/random.go
Normal file
|
@ -0,0 +1,34 @@
|
|||
package random
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
"time"
|
||||
)
|
||||
|
||||
// copypaste from standard math/rand
|
||||
type lockedSource struct {
|
||||
lk sync.Mutex
|
||||
src rand.Source
|
||||
}
|
||||
|
||||
func (r *lockedSource) Int63() (n int64) {
|
||||
r.lk.Lock()
|
||||
n = r.src.Int63()
|
||||
r.lk.Unlock()
|
||||
return
|
||||
}
|
||||
|
||||
func (r *lockedSource) Seed(seed int64) {
|
||||
r.lk.Lock()
|
||||
r.src.Seed(seed)
|
||||
r.lk.Unlock()
|
||||
}
|
||||
|
||||
// NewSource returns math/rand.Source safe for concurrent use and initialized
|
||||
// with current unix-nano timestamp
|
||||
func NewSource() rand.Source {
|
||||
return &lockedSource{
|
||||
src: rand.NewSource(time.Now().UnixNano()),
|
||||
}
|
||||
}
|
22
random/random_test.go
Normal file
22
random/random_test.go
Normal file
|
@ -0,0 +1,22 @@
|
|||
package random
|
||||
|
||||
import (
|
||||
"math/rand"
|
||||
"sync"
|
||||
"testing"
|
||||
)
|
||||
|
||||
// for go test -v -race
|
||||
func TestConcurrency(t *testing.T) {
|
||||
rnd := rand.New(NewSource())
|
||||
var wg sync.WaitGroup
|
||||
|
||||
for i := 0; i < 10; i++ {
|
||||
wg.Add(1)
|
||||
go func() {
|
||||
rnd.Int63()
|
||||
wg.Done()
|
||||
}()
|
||||
}
|
||||
wg.Wait()
|
||||
}
|
|
@ -2,9 +2,10 @@ package stringutils
|
|||
|
||||
import (
|
||||
"bytes"
|
||||
mathrand "math/rand"
|
||||
"math/rand"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/docker/docker/pkg/random"
|
||||
)
|
||||
|
||||
// Generate alpha only random stirng with length n
|
||||
|
@ -12,7 +13,7 @@ func GenerateRandomAlphaOnlyString(n int) string {
|
|||
// make a really long string
|
||||
letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||
b := make([]byte, n)
|
||||
r := mathrand.New(mathrand.NewSource(time.Now().UTC().UnixNano()))
|
||||
r := rand.New(random.NewSource())
|
||||
for i := range b {
|
||||
b[i] = letters[r.Intn(len(letters))]
|
||||
}
|
||||
|
@ -26,7 +27,7 @@ func GenerateRandomAsciiString(n int) string {
|
|||
"~!@#$%^&*()-_+={}[]\\|<,>.?/\"';:` "
|
||||
res := make([]byte, n)
|
||||
for i := 0; i < n; i++ {
|
||||
res[i] = chars[mathrand.Intn(len(chars))]
|
||||
res[i] = chars[rand.Intn(len(chars))]
|
||||
}
|
||||
return string(res)
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue