wait_time.go 1.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566
  1. // 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. package wait
  15. import "sync"
  16. type WaitTime interface {
  17. // Wait returns a chan that waits on the given logical deadline.
  18. // The chan will be triggered when Trigger is called with a
  19. // deadline that is later than the one it is waiting for.
  20. Wait(deadline uint64) <-chan struct{}
  21. // Trigger triggers all the waiting chans with an earlier logical deadline.
  22. Trigger(deadline uint64)
  23. }
  24. var closec chan struct{}
  25. func init() { closec = make(chan struct{}); close(closec) }
  26. type timeList struct {
  27. l sync.Mutex
  28. lastTriggerDeadline uint64
  29. m map[uint64]chan struct{}
  30. }
  31. func NewTimeList() *timeList {
  32. return &timeList{m: make(map[uint64]chan struct{})}
  33. }
  34. func (tl *timeList) Wait(deadline uint64) <-chan struct{} {
  35. tl.l.Lock()
  36. defer tl.l.Unlock()
  37. if tl.lastTriggerDeadline >= deadline {
  38. return closec
  39. }
  40. ch := tl.m[deadline]
  41. if ch == nil {
  42. ch = make(chan struct{})
  43. tl.m[deadline] = ch
  44. }
  45. return ch
  46. }
  47. func (tl *timeList) Trigger(deadline uint64) {
  48. tl.l.Lock()
  49. defer tl.l.Unlock()
  50. tl.lastTriggerDeadline = deadline
  51. for t, ch := range tl.m {
  52. if t <= deadline {
  53. delete(tl.m, t)
  54. close(ch)
  55. }
  56. }
  57. }