forked from tehsphinx/concurrent
-
Notifications
You must be signed in to change notification settings - Fork 0
/
bool_with_status.go
58 lines (49 loc) · 1.26 KB
/
bool_with_status.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
package concurrent
import (
"sync"
)
var eventChannelLen = 5
// NewBoolWithStatus creates a new concurrent bool with status channel
func NewBoolWithStatus() *BoolWithStatus {
return &BoolWithStatus{
events: []chan bool{},
}
}
// BoolWithStatus implements a cuncurrent bool
type BoolWithStatus struct {
bool bool
boolMutex sync.RWMutex
events []chan bool
}
// Set sets the bool to given value and returns if it changed or not. This
// can be used in race cases where a value could change inbetween the 'if'
// and setting the new value, making sure two routines executing simultaneously
// will not both get the same result checking the bool.
func (s *BoolWithStatus) Set(b bool) (ok bool) {
s.boolMutex.Lock()
defer s.boolMutex.Unlock()
ok = s.bool != b
if ok {
s.bool = b
for _, e := range s.events {
if len(e) < eventChannelLen {
e <- b
}
}
}
return ok
}
// Get gets the bool value
func (s *BoolWithStatus) Get() bool {
s.boolMutex.RLock()
defer s.boolMutex.RUnlock()
return s.bool
}
// GetStatusChannel returns a channel to listen to for status changes
func (s *BoolWithStatus) GetStatusChannel() <-chan bool {
ch := make(chan bool, eventChannelLen)
s.boolMutex.Lock()
s.events = append(s.events, ch)
s.boolMutex.Unlock()
return ch
}