package notifier import ( "context" "sync" ) // A Notifier is a synchronization primitive for waking upp all listeners at once. type Notifier struct { mutex sync.Mutex ch chan struct{} } // Broadcast wakes all listeners if there are any. func (notifier *Notifier) Broadcast() { notifier.mutex.Lock() if notifier.ch != nil { close(notifier.ch) notifier.ch = nil } notifier.mutex.Unlock() } // C gets the channel that'll close on the next notification. func (notifier *Notifier) C() <-chan struct{} { notifier.mutex.Lock() if notifier.ch == nil { notifier.ch = make(chan struct{}) } ch := notifier.ch notifier.mutex.Unlock() return ch } // Wait waits for the next `Broadcast` call, or the context's termination. func (notifier *Notifier) Wait(ctx context.Context) error { select { case <-notifier.C(): return nil case <-ctx.Done(): return ctx.Err() } }