1// 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} 47