This commit is contained in:
2026-02-19 10:07:43 +00:00
parent 007438e372
commit 6e637ecf77
1763 changed files with 60820 additions and 279516 deletions

81
vendor/github.com/creachadair/msync/trigger/trigger.go generated vendored Normal file
View File

@@ -0,0 +1,81 @@
// Package trigger implements channel-based condition variable.
package trigger
import "sync"
// A Cond is a condition shared by multiple goroutines. The [Cond.Ready]
// method returns a channel that is closed when the condition is activated.
//
// When a condition is first created it is inactive. While inactive, reads on
// the ready channel will block. The condition remains inactive until
// [Cond.Set] or [Cond.Signal] is called, either of which causes the current
// ready channel to be closed (and thus deliver a zero value). Once a condition
// has been activated, it remains active until it is reset. Use [Cond.Reset] to
// make it inactive again.
//
// The [Cond.Signal] method activates and then immediately resets the
// condition, acting as Set and Reset done in a single step.
//
// A zero Cond is ready for use, and is inactive, but must not be copied after
// any of its methods have been called.
type Cond struct {
μ sync.Mutex
ch chan struct{}
closed bool
// The signal channel is lazily initialized by the first waiter.
}
// New constructs a new inactive [Cond].
func New() *Cond { return new(Cond) }
// Signal activates and immediately resets the condition. If the condition was
// already active, this is equivalent to [Cond.Reset].
func (c *Cond) Signal() {
c.μ.Lock()
defer c.μ.Unlock()
if c.ch != nil && !c.closed {
close(c.ch) // wake any pending waiters
}
c.ch = nil
c.closed = false
}
// Set activates the condition. If it was already active, Set has no effect.
func (c *Cond) Set() {
c.μ.Lock()
defer c.μ.Unlock()
if c.ch == nil {
c.ch = make(chan struct{})
}
if !c.closed {
close(c.ch)
c.closed = true
}
}
// Reset resets the condition. If it was already inactive, Reset has no effect.
func (c *Cond) Reset() {
c.μ.Lock()
defer c.μ.Unlock()
if c.closed {
c.ch = nil
c.closed = false
}
}
// Ready returns a channel that is closed when c is activated. If c is active
// when Ready is called, the returned channel will already be closed.
func (c *Cond) Ready() <-chan struct{} {
c.μ.Lock()
defer c.μ.Unlock()
if c.ch == nil {
c.ch = make(chan struct{})
c.closed = false
}
return c.ch
}