Make unbounded channels explicit.
We used to have unbounded channels embedded within rtpconn and webClient. Make the structure explicit and testable.
This commit is contained in:
@@ -0,0 +1,47 @@
|
||||
package unbounded
|
||||
|
||||
import (
|
||||
"sync"
|
||||
)
|
||||
|
||||
// Type Channel implements an unbounded channel
|
||||
type Channel[T any] struct {
|
||||
// Ch triggers whenever the channel becomes non-empty
|
||||
Ch chan struct{}
|
||||
|
||||
mu sync.Mutex
|
||||
queue []T
|
||||
}
|
||||
|
||||
// New creates a new unbounded channel
|
||||
func New[T any]() *Channel[T] {
|
||||
return &Channel[T]{
|
||||
Ch: make(chan struct{}, 1),
|
||||
}
|
||||
}
|
||||
|
||||
// Put inserts a new element into ch.
|
||||
// If ch was previously empty, it triggers ch.Ch.
|
||||
func (ch *Channel[T]) Put(v T) {
|
||||
ch.mu.Lock()
|
||||
empty := len(ch.queue) == 0
|
||||
ch.queue = append(ch.queue, v)
|
||||
ch.mu.Unlock()
|
||||
|
||||
if empty {
|
||||
select {
|
||||
case ch.Ch <- struct{}{}:
|
||||
default:
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Get removes all the elements of ch.
|
||||
// It is usually called when ch.Ch triggers, but may be called at any time.
|
||||
func (ch *Channel[T]) Get() []T {
|
||||
ch.mu.Lock()
|
||||
defer ch.mu.Unlock()
|
||||
queue := ch.queue
|
||||
ch.queue = nil
|
||||
return queue
|
||||
}
|
||||
Reference in New Issue
Block a user