cond.go 937 B

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758
  1. package asyncbuffer
  2. import (
  3. "sync"
  4. )
  5. type condCh = chan struct{}
  6. // Cond signals that an event has occurred to a multiple waiters.
  7. type Cond struct {
  8. mu sync.RWMutex
  9. ch condCh
  10. closeOnce sync.Once
  11. }
  12. // NewCond creates a new Ticker instance with an initialized channel.
  13. func NewCond() *Cond {
  14. return &Cond{
  15. ch: make(condCh),
  16. }
  17. }
  18. // Tick signals that an event has occurred by closing the channel.
  19. func (t *Cond) Tick() {
  20. t.mu.Lock()
  21. defer t.mu.Unlock()
  22. if t.ch != nil {
  23. close(t.ch)
  24. t.ch = make(condCh)
  25. }
  26. }
  27. // Wait blocks until the channel is closed, indicating that an event has occurred.
  28. func (t *Cond) Wait() {
  29. t.mu.RLock()
  30. ch := t.ch
  31. t.mu.RUnlock()
  32. if ch == nil {
  33. return
  34. }
  35. <-ch
  36. }
  37. // Close closes the ticker channel and prevents further ticks.
  38. func (t *Cond) Close() {
  39. t.closeOnce.Do(func() {
  40. t.mu.Lock()
  41. defer t.mu.Unlock()
  42. if t.ch != nil {
  43. close(t.ch)
  44. t.ch = nil
  45. }
  46. })
  47. }