booleanfuse.go 909 B

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051
  1. package h2mux
  2. import "sync"
  3. // BooleanFuse is a data structure that can be set once to a particular value using Fuse(value).
  4. // Subsequent calls to Fuse() will have no effect.
  5. type BooleanFuse struct {
  6. value int32
  7. mu sync.Mutex
  8. cond *sync.Cond
  9. }
  10. func NewBooleanFuse() *BooleanFuse {
  11. f := &BooleanFuse{}
  12. f.cond = sync.NewCond(&f.mu)
  13. return f
  14. }
  15. // Value gets the value
  16. func (f *BooleanFuse) Value() bool {
  17. // 0: unset
  18. // 1: set true
  19. // 2: set false
  20. f.mu.Lock()
  21. defer f.mu.Unlock()
  22. return f.value == 1
  23. }
  24. func (f *BooleanFuse) Fuse(result bool) {
  25. f.mu.Lock()
  26. defer f.mu.Unlock()
  27. newValue := int32(2)
  28. if result {
  29. newValue = 1
  30. }
  31. if f.value == 0 {
  32. f.value = newValue
  33. f.cond.Broadcast()
  34. }
  35. }
  36. // Await blocks until Fuse has been called at least once.
  37. func (f *BooleanFuse) Await() bool {
  38. f.mu.Lock()
  39. defer f.mu.Unlock()
  40. for f.value == 0 {
  41. f.cond.Wait()
  42. }
  43. return f.value == 1
  44. }