...
1
2
3
4
5
6
7 package quic
8
9 import "context"
10
11
12
13
14
15
16 type gate struct {
17
18
19 set chan struct{}
20 unset chan struct{}
21 }
22
23
24 func newGate() gate {
25 g := newLockedGate()
26 g.unlock(false)
27 return g
28 }
29
30
31 func newLockedGate() gate {
32 return gate{
33 set: make(chan struct{}, 1),
34 unset: make(chan struct{}, 1),
35 }
36 }
37
38
39
40 func (g *gate) lock() (set bool) {
41 select {
42 case <-g.set:
43 return true
44 case <-g.unset:
45 return false
46 }
47 }
48
49
50
51 func (g *gate) waitAndLock(ctx context.Context, testHooks connTestHooks) error {
52 if testHooks != nil {
53 return testHooks.waitUntil(ctx, g.lockIfSet)
54 }
55 select {
56 case <-g.set:
57 return nil
58 default:
59 }
60 select {
61 case <-g.set:
62 return nil
63 case <-ctx.Done():
64 return ctx.Err()
65 }
66 }
67
68
69 func (g *gate) lockIfSet() (acquired bool) {
70 select {
71 case <-g.set:
72 return true
73 default:
74 return false
75 }
76 }
77
78
79 func (g *gate) unlock(set bool) {
80 if set {
81 g.set <- struct{}{}
82 } else {
83 g.unset <- struct{}{}
84 }
85 }
86
87
88
89 func (g *gate) unlockFunc(f func() bool) {
90 g.unlock(f())
91 }
92
View as plain text