Skip to content

Commit

Permalink
Merge pull request #430 from qnnn/master
Browse files Browse the repository at this point in the history
Fix concurrency unsafety error of rand.Intn.
  • Loading branch information
bojand authored May 5, 2024
2 parents 2777ea8 + fa16bdc commit f778079
Show file tree
Hide file tree
Showing 2 changed files with 32 additions and 7 deletions.
28 changes: 21 additions & 7 deletions runner/calldata.go
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ import (
htmlTemplate "html/template"
"math/rand"
"strings"
"sync"
"text/template"
"text/template/parse"
"time"
Expand All @@ -19,8 +20,11 @@ import (
const charset = "abcdefghijklmnopqrstuvwxyz" +
"ABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789"

var seededRand *rand.Rand = rand.New(
rand.NewSource(time.Now().UnixNano()))
var seededRandPool = sync.Pool{
New: func() interface{} {
return rand.New(rand.NewSource(time.Now().UnixNano()))
},
}

var sprigFuncMap htmlTemplate.FuncMap = sprig.FuncMap()

Expand Down Expand Up @@ -178,7 +182,10 @@ func (td *CallData) ExecuteData(data string) ([]byte, error) {
if len(data) > 0 {
input := []byte(data)
tpl, err := td.execute(data)
if err == nil && tpl != nil {
if err != nil {
return nil, err
}
if tpl != nil {
input = tpl.Bytes()
}

Expand Down Expand Up @@ -227,15 +234,21 @@ const minLen = 2

func stringWithCharset(length int, charset string) string {
b := make([]byte, length)
rng := seededRandPool.Get().(*rand.Rand)
defer seededRandPool.Put(rng)
for i := range b {
b[i] = charset[seededRand.Intn(len(charset))]
b[i] = charset[rng.Intn(len(charset))]
}
return string(b)
}

func randomString(length int) string {
if length <= 0 {
length = seededRand.Intn(maxLen-minLen+1) + minLen
func() {
rng := seededRandPool.Get().(*rand.Rand)
defer seededRandPool.Put(rng)
length = rng.Intn(maxLen-minLen+1) + minLen
}()
}

return stringWithCharset(length, charset)
Expand All @@ -249,6 +262,7 @@ func randomInt(min, max int) int {
if max <= 0 {
max = 1
}

return seededRand.Intn(max-min) + min
rng := seededRandPool.Get().(*rand.Rand)
defer seededRandPool.Put(rng)
return rng.Intn(max-min) + min
}
11 changes: 11 additions & 0 deletions runner/calldata_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -332,3 +332,14 @@ func TestCallTemplateData_ExecuteFuncs(t *testing.T) {
assert.Equal(t, `{"trace_id":"ABCABCABC"}`, string(r))
})
}

func BenchmarkCallData_randomString(b *testing.B) {
b.N = 100000000

Check failure on line 337 in runner/calldata_test.go

View workflow job for this annotation

GitHub Actions / build

SA3001: should not assign to b.N (staticcheck)
b.SetParallelism(1024)
b.RunParallel(func(pb *testing.PB) {
for pb.Next() {
_ = randomString(10)
}
})
b.Logf("pass")
}

0 comments on commit f778079

Please sign in to comment.