pomerium/internal/signal/signal.go
2021-04-22 10:58:13 -04:00

49 lines
1.1 KiB
Go

// Package signal provides mechanism for notifying multiple listeners when something happened.
package signal
import (
"context"
"sync"
)
// A Signal is used to let multiple listeners know when something happened.
type Signal struct {
mu sync.Mutex
chs map[chan context.Context]struct{}
}
// New creates a new Signal.
func New() *Signal {
return &Signal{
chs: make(map[chan context.Context]struct{}),
}
}
// Broadcast signals all the listeners. Broadcast never blocks.
func (s *Signal) Broadcast(ctx context.Context) {
s.mu.Lock()
for ch := range s.chs {
select {
case ch <- ctx:
default:
}
}
s.mu.Unlock()
}
// Bind creates a new listening channel bound to the signal. The channel used has a size of 1
// and any given broadcast will signal at least one event, but may signal more than one.
func (s *Signal) Bind() chan context.Context {
ch := make(chan context.Context, 1)
s.mu.Lock()
s.chs[ch] = struct{}{}
s.mu.Unlock()
return ch
}
// Unbind stops the listening channel bound to the signal.
func (s *Signal) Unbind(ch chan context.Context) {
s.mu.Lock()
delete(s.chs, ch)
s.mu.Unlock()
}