rand.go 1.2 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556
  1. // Unless explicitly stated otherwise all files in this repository are licensed
  2. // under the Apache License Version 2.0.
  3. // This product includes software developed at Datadog (https://www.datadoghq.com/).
  4. // Copyright 2016 Datadog, Inc.
  5. package tracer
  6. import (
  7. cryptorand "crypto/rand"
  8. "math"
  9. "math/big"
  10. "math/rand"
  11. "sync"
  12. "time"
  13. "gopkg.in/DataDog/dd-trace-go.v1/internal/log"
  14. )
  15. // random holds a thread-safe source of random numbers.
  16. var random *rand.Rand
  17. func init() {
  18. var seed int64
  19. n, err := cryptorand.Int(cryptorand.Reader, big.NewInt(math.MaxInt64))
  20. if err == nil {
  21. seed = n.Int64()
  22. } else {
  23. log.Warn("cannot generate random seed: %v; using current time", err)
  24. seed = time.Now().UnixNano()
  25. }
  26. random = rand.New(&safeSource{
  27. source: rand.NewSource(seed),
  28. })
  29. }
  30. // safeSource holds a thread-safe implementation of rand.Source64.
  31. type safeSource struct {
  32. source rand.Source
  33. sync.Mutex
  34. }
  35. func (rs *safeSource) Int63() int64 {
  36. rs.Lock()
  37. n := rs.source.Int63()
  38. rs.Unlock()
  39. return n
  40. }
  41. func (rs *safeSource) Uint64() uint64 { return uint64(rs.Int63()) }
  42. func (rs *safeSource) Seed(seed int64) {
  43. rs.Lock()
  44. rs.source.Seed(seed)
  45. rs.Unlock()
  46. }