blob: 297e48a47d76f3866bac6b03563e994492711437 [file] [log] [blame]
khenaidooffe076b2019-01-15 16:08:08 -05001// Copyright 2015 The etcd Authors
2//
3// Licensed under the Apache License, Version 2.0 (the "License");
4// you may not use this file except in compliance with the License.
5// You may obtain a copy of the License at
6//
7// http://www.apache.org/licenses/LICENSE-2.0
8//
9// Unless required by applicable law or agreed to in writing, software
10// distributed under the License is distributed on an "AS IS" BASIS,
11// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12// See the License for the specific language governing permissions and
13// limitations under the License.
14
15package wait
16
17import "sync"
18
19type WaitTime interface {
20 // Wait returns a chan that waits on the given logical deadline.
21 // The chan will be triggered when Trigger is called with a
22 // deadline that is later than the one it is waiting for.
23 Wait(deadline uint64) <-chan struct{}
24 // Trigger triggers all the waiting chans with an earlier logical deadline.
25 Trigger(deadline uint64)
26}
27
28var closec chan struct{}
29
30func init() { closec = make(chan struct{}); close(closec) }
31
32type timeList struct {
33 l sync.Mutex
34 lastTriggerDeadline uint64
35 m map[uint64]chan struct{}
36}
37
38func NewTimeList() *timeList {
39 return &timeList{m: make(map[uint64]chan struct{})}
40}
41
42func (tl *timeList) Wait(deadline uint64) <-chan struct{} {
43 tl.l.Lock()
44 defer tl.l.Unlock()
45 if tl.lastTriggerDeadline >= deadline {
46 return closec
47 }
48 ch := tl.m[deadline]
49 if ch == nil {
50 ch = make(chan struct{})
51 tl.m[deadline] = ch
52 }
53 return ch
54}
55
56func (tl *timeList) Trigger(deadline uint64) {
57 tl.l.Lock()
58 defer tl.l.Unlock()
59 tl.lastTriggerDeadline = deadline
60 for t, ch := range tl.m {
61 if t <= deadline {
62 delete(tl.m, t)
63 close(ch)
64 }
65 }
66}