atomic.go 1.8 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273
  1. // Go MySQL Driver - A MySQL-Driver for Go's database/sql package
  2. //
  3. // Copyright 2017 The Go-MySQL-Driver Authors. All rights reserved.
  4. //
  5. // This Source Code Form is subject to the terms of the Mozilla Public
  6. // License, v. 2.0. If a copy of the MPL was not distributed with this file,
  7. // You can obtain one at http://mozilla.org/MPL/2.0/.
  8. package atomic
  9. import (
  10. "sync/atomic"
  11. )
  12. // noCopy may be embedded into structs which must not be copied
  13. // after the first use.
  14. //
  15. // See https://github.com/golang/go/issues/8005#issuecomment-190753527
  16. // for details.
  17. type noCopy struct{}
  18. // Lock is a no-op used by -copylocks checker from `go vet`.
  19. func (*noCopy) Lock() {}
  20. // Bool is a wrapper around uint32 for usage as a boolean value with
  21. // atomic access.
  22. type Bool struct {
  23. _noCopy noCopy
  24. value uint32
  25. }
  26. // IsSet returns wether the current boolean value is true
  27. func (b *Bool) IsSet() bool {
  28. return atomic.LoadUint32(&b.value) > 0
  29. }
  30. // Set sets the value of the bool regardless of the previous value
  31. func (b *Bool) Set(value bool) {
  32. if value {
  33. atomic.StoreUint32(&b.value, 1)
  34. } else {
  35. atomic.StoreUint32(&b.value, 0)
  36. }
  37. }
  38. // TrySet sets the value of the bool and returns wether the value changed
  39. func (b *Bool) TrySet(value bool) bool {
  40. if value {
  41. return atomic.SwapUint32(&b.value, 1) == 0
  42. }
  43. return atomic.SwapUint32(&b.value, 0) > 0
  44. }
  45. // Error is a wrapper for atomically accessed error values
  46. type Error struct {
  47. _noCopy noCopy
  48. value atomic.Value
  49. }
  50. // Set sets the error value regardless of the previous value.
  51. // The value must not be nil
  52. func (e *Error) Set(value error) {
  53. e.value.Store(value)
  54. }
  55. // Value returns the current error value
  56. func (e *Error) Value() error {
  57. if v := e.value.Load(); v != nil {
  58. // this will panic if the value doesn't implement the error interface
  59. return v.(error)
  60. }
  61. return nil
  62. }