-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy pathcond.go
67 lines (57 loc) · 1.04 KB
/
cond.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
60
61
62
63
64
65
66
67
// derived from here: http://stackoverflow.com/questions/29923666/waiting-on-a-sync-cond-with-a-timeout/41731499
package connpool
import (
"sync"
"time"
)
type TMOCond struct {
L sync.Locker
ch chan bool
}
func NewTMOCond(l sync.Locker) *TMOCond {
return &TMOCond{ ch: make(chan bool), L: l }
}
func (t *TMOCond) Wait() {
t.L.Unlock()
<-t.ch
t.L.Lock()
}
func (t *TMOCond) WaitOrTimeout(d time.Duration) bool {
tmo := time.NewTimer(d)
t.L.Unlock()
var r bool
select {
case <-tmo.C:
r = false
case <-t.ch:
r = true
}
if !tmo.Stop() {
select {
case <- tmo.C:
default:
}
}
t.L.Lock()
return r
}
func (t *TMOCond) Signal() {
t.signal()
}
func (t *TMOCond) Broadcast() {
for {
// Stop when we run out of waiters
//
if !t.signal() {
return
}
}
}
func (t *TMOCond) signal() bool {
select {
case t.ch <- true:
return true
default:
return false
}
}