2024-10-15 20:10:30 +00:00
|
|
|
package supervisor
|
2018-05-01 23:45:06 +00:00
|
|
|
|
|
|
|
import "sync"
|
|
|
|
|
2024-10-15 20:10:30 +00:00
|
|
|
// booleanFuse is a data structure that can be set once to a particular value using Fuse(value).
|
2018-05-01 23:45:06 +00:00
|
|
|
// Subsequent calls to Fuse() will have no effect.
|
2024-10-15 20:10:30 +00:00
|
|
|
type booleanFuse struct {
|
2018-05-01 23:45:06 +00:00
|
|
|
value int32
|
|
|
|
mu sync.Mutex
|
|
|
|
cond *sync.Cond
|
|
|
|
}
|
|
|
|
|
2024-10-15 20:10:30 +00:00
|
|
|
func newBooleanFuse() *booleanFuse {
|
|
|
|
f := &booleanFuse{}
|
2018-05-01 23:45:06 +00:00
|
|
|
f.cond = sync.NewCond(&f.mu)
|
|
|
|
return f
|
|
|
|
}
|
|
|
|
|
|
|
|
// Value gets the value
|
2024-10-15 20:10:30 +00:00
|
|
|
func (f *booleanFuse) Value() bool {
|
2018-05-01 23:45:06 +00:00
|
|
|
// 0: unset
|
|
|
|
// 1: set true
|
|
|
|
// 2: set false
|
|
|
|
f.mu.Lock()
|
|
|
|
defer f.mu.Unlock()
|
|
|
|
return f.value == 1
|
|
|
|
}
|
|
|
|
|
2024-10-15 20:10:30 +00:00
|
|
|
func (f *booleanFuse) Fuse(result bool) {
|
2018-05-01 23:45:06 +00:00
|
|
|
f.mu.Lock()
|
|
|
|
defer f.mu.Unlock()
|
|
|
|
newValue := int32(2)
|
|
|
|
if result {
|
|
|
|
newValue = 1
|
|
|
|
}
|
|
|
|
if f.value == 0 {
|
|
|
|
f.value = newValue
|
|
|
|
f.cond.Broadcast()
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// Await blocks until Fuse has been called at least once.
|
2024-10-15 20:10:30 +00:00
|
|
|
func (f *booleanFuse) Await() bool {
|
2018-05-01 23:45:06 +00:00
|
|
|
f.mu.Lock()
|
|
|
|
defer f.mu.Unlock()
|
|
|
|
for f.value == 0 {
|
|
|
|
f.cond.Wait()
|
|
|
|
}
|
|
|
|
return f.value == 1
|
|
|
|
}
|