-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathcounter_channel.go
52 lines (45 loc) · 1.12 KB
/
counter_channel.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
package counter
// Thread-safe counter
// Uses 2 Channels to coordinate reads and writes.
// Must be initialized with NewCounterChannel().
type CounterChannel struct {
readCh chan uint64
writeCh chan int
}
// NewCounterChannel() is required to initialize a Counter.
func NewCounterChannel() *CounterChannel {
c := &CounterChannel{
readCh: make(chan uint64),
writeCh: make(chan int),
}
// The actual counter value lives inside this goroutine.
// It can only be accessed for R/W via one of the channels.
go func() {
var count uint64 = 0
for {
select {
// Reading from readCh is equivalent to reading count.
case c.readCh <- count:
// Writing to the writeCh increments count.
case <-c.writeCh:
count++
}
}
}()
return c
}
// Increment counter by pushing an arbitrary int to the write channel.
func (c *CounterChannel) Inc() {
c.check()
c.writeCh <- 1
}
// Get current counter value from the read channel.
func (c *CounterChannel) Get() uint64 {
c.check()
return <-c.readCh
}
func (c *CounterChannel) check() {
if c.readCh == nil {
panic("Uninitialized Counter, requires NewCounterChannel()")
}
}