mirror of https://github.com/golang/go.git
67 lines
1.8 KiB
Go
67 lines
1.8 KiB
Go
// Copyright 2022 The Go Authors. All rights reserved.
|
|
// Use of this source code is governed by a BSD-style
|
|
// license that can be found in the LICENSE file.
|
|
|
|
package chans
|
|
|
|
import "runtime"
|
|
|
|
// Ranger returns a Sender and a Receiver. The Receiver provides a
|
|
// Next method to retrieve values. The Sender provides a Send method
|
|
// to send values and a Close method to stop sending values. The Next
|
|
// method indicates when the Sender has been closed, and the Send
|
|
// method indicates when the Receiver has been freed.
|
|
//
|
|
// This is a convenient way to exit a goroutine sending values when
|
|
// the receiver stops reading them.
|
|
func Ranger[T any]() (*Sender[T], *Receiver[T]) {
|
|
c := make(chan T)
|
|
d := make(chan bool)
|
|
s := &Sender[T]{values: c, done: d}
|
|
r := &Receiver[T]{values: c, done: d}
|
|
runtime.SetFinalizer(r, r.finalize)
|
|
return s, r
|
|
}
|
|
|
|
// A sender is used to send values to a Receiver.
|
|
type Sender[T any] struct {
|
|
values chan<- T
|
|
done <-chan bool
|
|
}
|
|
|
|
// Send sends a value to the receiver. It returns whether any more
|
|
// values may be sent; if it returns false the value was not sent.
|
|
func (s *Sender[T]) Send(v T) bool {
|
|
select {
|
|
case s.values <- v:
|
|
return true
|
|
case <-s.done:
|
|
return false
|
|
}
|
|
}
|
|
|
|
// Close tells the receiver that no more values will arrive.
|
|
// After Close is called, the Sender may no longer be used.
|
|
func (s *Sender[T]) Close() {
|
|
close(s.values)
|
|
}
|
|
|
|
// A Receiver receives values from a Sender.
|
|
type Receiver[T any] struct {
|
|
values <-chan T
|
|
done chan<- bool
|
|
}
|
|
|
|
// Next returns the next value from the channel. The bool result
|
|
// indicates whether the value is valid, or whether the Sender has
|
|
// been closed and no more values will be received.
|
|
func (r *Receiver[T]) Next() (T, bool) {
|
|
v, ok := <-r.values
|
|
return v, ok
|
|
}
|
|
|
|
// finalize is a finalizer for the receiver.
|
|
func (r *Receiver[T]) finalize() {
|
|
close(r.done)
|
|
}
|