-
Notifications
You must be signed in to change notification settings - Fork 2
/
Copy pathcandy_mainloop.go
59 lines (51 loc) · 1.06 KB
/
candy_mainloop.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
59
package sugar
import (
"sync/atomic"
"time"
)
func (candy *candy) Invoke(action func()) {
if atomic.LoadUint32(&candy.isRunning) == 0 {
panic("The candy loop is not running")
}
request := &actionRequest{action: action, done: make(chan struct{})}
candy.requests <- request
<-request.done
}
func (candy *candy) RunLoop() {
if !atomic.CompareAndSwapUint32(&candy.isRunning, 0, 1) {
panic("The candy loop is already running")
}
defer func() {
atomic.StoreUint32(&candy.isRunning, 0)
}()
candy.stop = make(chan struct{})
// keep sending gtk-server callback request
go func() {
for {
select {
case candy.requests <- candy.cbRequest:
<-candy.cbRequest.done
time.Sleep(_MAINLOOP_TIMEGAP)
case <-candy.stop:
return
}
}
}()
mainLoop:
for {
select {
case request := <-candy.requests:
if nil != request.action {
request.action()
}
request.done <- struct{}{}
case <-candy.stop:
break mainLoop
}
}
}
func (candy *candy) StopLoop() {
if atomic.CompareAndSwapUint32(&candy.isRunning, 1, 0) {
close(candy.stop)
}
}