// Copyright 2024 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 gate contains an alternative condition variable.
package gate import // A Gate is a monitor (mutex + condition variable) with one bit of state. // // The condition may be either set or unset. // Lock operations may be unconditional, or wait for the condition to be set. // Unlock operations record the new state of the condition. type Gate struct { // When unlocked, exactly one of set or unset contains a value. // When locked, neither chan contains a value. set chan struct{} unset chan struct{} } // New returns a new, unlocked gate. func ( bool) Gate { := Gate{ set: make(chan struct{}, 1), unset: make(chan struct{}, 1), } .Unlock() return } // Lock acquires the gate unconditionally. // It reports whether the condition is set. func ( *Gate) () ( bool) { select { case <-.set: return true case <-.unset: return false } } // WaitAndLock waits until the condition is set before acquiring the gate. // If the context expires, WaitAndLock returns an error and does not acquire the gate. func ( *Gate) ( context.Context) error { select { case <-.set: return nil default: } select { case <-.set: return nil case <-.Done(): return .Err() } } // LockIfSet acquires the gate if and only if the condition is set. func ( *Gate) () ( bool) { select { case <-.set: return true default: return false } } // Unlock sets the condition and releases the gate. func ( *Gate) ( bool) { if { .set <- struct{}{} } else { .unset <- struct{}{} } }