sync: Don't panic on double close of Gate, return error instead

This commit is contained in:
Sasha Koshka 2024-11-11 11:38:59 -05:00
parent 709f41a974
commit 9fd40a37b8

View File

@ -2,6 +2,16 @@ package usync
import "sync" import "sync"
// Error defines errors that this package can produce
type Error string; const (
ErrAlreadyClosed Error = "AlreadyClosed"
)
// Error fullfills the error interface.
func (err Error) Error () string {
return string(err)
}
// Gate wraps a channel and allows the receiver to abruptly stop receiving // Gate wraps a channel and allows the receiver to abruptly stop receiving
// messages without causing the sender to lock up. // messages without causing the sender to lock up.
type Gate[T any] struct { type Gate[T any] struct {
@ -47,6 +57,7 @@ func (this *Gate[T]) Receive () <- chan T {
// Close closes the gate, drains all remaining messages, and closes the channel. // Close closes the gate, drains all remaining messages, and closes the channel.
func (this *Gate[T]) Close () error { func (this *Gate[T]) Close () error {
this.lock.Lock() this.lock.Lock()
if !this.open { return ErrAlreadyClosed }
this.open = false this.open = false
this.lock.Unlock() this.lock.Unlock()
for len(this.channel) > 0 { <- this.channel } for len(this.channel) > 0 { <- this.channel }