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 (
|
import (
|
||||||
"fmt"
|
"fmt"
|
||||||
"math/rand"
|
"math/rand"
|
||||||
"time"
|
|
||||||
|
"github.com/docker/docker/pkg/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
var (
|
var (
|
||||||
|
@ -309,7 +310,7 @@ var (
|
||||||
"yonath",
|
"yonath",
|
||||||
}
|
}
|
||||||
|
|
||||||
rnd = rand.New(rand.NewSource(time.Now().UnixNano()))
|
rnd = rand.New(random.NewSource())
|
||||||
)
|
)
|
||||||
|
|
||||||
func GetRandomName(retry int) string {
|
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 (
|
import (
|
||||||
"bytes"
|
"bytes"
|
||||||
mathrand "math/rand"
|
"math/rand"
|
||||||
"strings"
|
"strings"
|
||||||
"time"
|
|
||||||
|
"github.com/docker/docker/pkg/random"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Generate alpha only random stirng with length n
|
// Generate alpha only random stirng with length n
|
||||||
|
@ -12,7 +13,7 @@ func GenerateRandomAlphaOnlyString(n int) string {
|
||||||
// make a really long string
|
// make a really long string
|
||||||
letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
letters := []byte("abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ")
|
||||||
b := make([]byte, n)
|
b := make([]byte, n)
|
||||||
r := mathrand.New(mathrand.NewSource(time.Now().UTC().UnixNano()))
|
r := rand.New(random.NewSource())
|
||||||
for i := range b {
|
for i := range b {
|
||||||
b[i] = letters[r.Intn(len(letters))]
|
b[i] = letters[r.Intn(len(letters))]
|
||||||
}
|
}
|
||||||
|
@ -26,7 +27,7 @@ func GenerateRandomAsciiString(n int) string {
|
||||||
"~!@#$%^&*()-_+={}[]\\|<,>.?/\"';:` "
|
"~!@#$%^&*()-_+={}[]\\|<,>.?/\"';:` "
|
||||||
res := make([]byte, n)
|
res := make([]byte, n)
|
||||||
for i := 0; i < n; i++ {
|
for i := 0; i < n; i++ {
|
||||||
res[i] = chars[mathrand.Intn(len(chars))]
|
res[i] = chars[rand.Intn(len(chars))]
|
||||||
}
|
}
|
||||||
return string(res)
|
return string(res)
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in a new issue