notifier.go 907 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. package signal
  2. import "sync"
  3. // Notifier is a utility for notifying changes. The change producer may notify changes multiple time, and the consumer may get notified asynchronously.
  4. type Notifier struct {
  5. sync.Mutex
  6. waiters []chan struct{}
  7. notCosumed bool
  8. }
  9. // NewNotifier creates a new Notifier.
  10. func NewNotifier() *Notifier {
  11. return &Notifier{}
  12. }
  13. // Signal signals a change, usually by producer. This method never blocks.
  14. func (n *Notifier) Signal() {
  15. n.Lock()
  16. defer n.Unlock()
  17. if len(n.waiters) == 0 {
  18. n.notCosumed = true
  19. return
  20. }
  21. for _, w := range n.waiters {
  22. close(w)
  23. }
  24. n.waiters = make([]chan struct{}, 0, 8)
  25. }
  26. // Wait returns a channel for waiting for changes.
  27. func (n *Notifier) Wait() <-chan struct{} {
  28. n.Lock()
  29. defer n.Unlock()
  30. w := make(chan struct{})
  31. if n.notCosumed {
  32. n.notCosumed = false
  33. close(w)
  34. return w
  35. }
  36. n.waiters = append(n.waiters, w)
  37. return w
  38. }