2017-10-16 11:44:03 +00:00
|
|
|
package h2mux
|
|
|
|
|
2017-11-28 13:41:29 +00:00
|
|
|
import "sync"
|
2017-10-16 11:44:03 +00:00
|
|
|
|
|
|
|
// BooleanFuse is a data structure that can be set once to a particular value using Fuse(value).
|
|
|
|
// Subsequent calls to Fuse() will have no effect.
|
|
|
|
type BooleanFuse struct {
|
|
|
|
value int32
|
2017-11-28 13:41:29 +00:00
|
|
|
mu sync.Mutex
|
|
|
|
cond *sync.Cond
|
|
|
|
}
|
|
|
|
|
|
|
|
func NewBooleanFuse() *BooleanFuse {
|
|
|
|
f := &BooleanFuse{}
|
|
|
|
f.cond = sync.NewCond(&f.mu)
|
|
|
|
return f
|
2017-10-16 11:44:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
// Value gets the value
|
|
|
|
func (f *BooleanFuse) Value() bool {
|
|
|
|
// 0: unset
|
|
|
|
// 1: set true
|
|
|
|
// 2: set false
|
2017-11-28 13:41:29 +00:00
|
|
|
f.mu.Lock()
|
|
|
|
defer f.mu.Unlock()
|
|
|
|
return f.value == 1
|
2017-10-16 11:44:03 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (f *BooleanFuse) Fuse(result bool) {
|
2017-11-28 13:41:29 +00:00
|
|
|
f.mu.Lock()
|
|
|
|
defer f.mu.Unlock()
|
2017-10-16 11:44:03 +00:00
|
|
|
newValue := int32(2)
|
|
|
|
if result {
|
|
|
|
newValue = 1
|
|
|
|
}
|
2017-11-28 13:41:29 +00:00
|
|
|
if f.value == 0 {
|
|
|
|
f.value = newValue
|
|
|
|
f.cond.Broadcast()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Await blocks until Fuse has been called at least once.
|
|
|
|
func (f *BooleanFuse) Await() bool {
|
|
|
|
f.mu.Lock()
|
|
|
|
defer f.mu.Unlock()
|
|
|
|
for f.value == 0 {
|
|
|
|
f.cond.Wait()
|
|
|
|
}
|
|
|
|
return f.value == 1
|
2017-10-16 11:44:03 +00:00
|
|
|
}
|