blob: 9875f7f55cbd1230a71bef97f7837745e9e228aa [file] [log] [blame]
Takahiro Suzuki241c10e2020-12-17 20:17:57 +09001// Copyright (c) 2017 Uber Technologies, Inc.
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package utils
16
17import (
18 "math/rand"
19 "sync"
20)
21
22// lockedSource allows a random number generator to be used by multiple goroutines concurrently.
23// The code is very similar to math/rand.lockedSource, which is unfortunately not exposed.
24type lockedSource struct {
25 mut sync.Mutex
26 src rand.Source
27}
28
29// NewRand returns a rand.Rand that is threadsafe.
30func NewRand(seed int64) *rand.Rand {
31 return rand.New(&lockedSource{src: rand.NewSource(seed)})
32}
33
34func (r *lockedSource) Int63() (n int64) {
35 r.mut.Lock()
36 n = r.src.Int63()
37 r.mut.Unlock()
38 return
39}
40
41// Seed implements Seed() of Source
42func (r *lockedSource) Seed(seed int64) {
43 r.mut.Lock()
44 r.src.Seed(seed)
45 r.mut.Unlock()
46}