mirror of
https://github.com/jech/galene.git
synced 2024-11-23 00:55:58 +01:00
48 lines
871 B
Go
48 lines
871 B
Go
|
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
|
||
|
}
|