/* * Copyright (c) 2022 tursom. All rights reserved. * Use of this source code is governed by a GPL-3 * license that can be found in the LICENSE file. */ package concurrent import ( "sync" "time" ) type ( Cond interface { Signal() Broadcast() // Wait wait within unlocked environment Wait() // LockedWait wait within locked environment LockedWait() WaitOrTimeout(timeout time.Duration) bool } CondImpl sync.Cond ) func NewCond(l sync.Locker) Cond { return (*CondImpl)(sync.NewCond(l)) } func (c *CondImpl) Signal() { (*sync.Cond)(c).Signal() } func (c *CondImpl) Broadcast() { (*sync.Cond)(c).Broadcast() } func (c *CondImpl) Wait() { c.L.Lock() defer c.L.Unlock() (*sync.Cond)(c).Wait() } func (c *CondImpl) LockedWait() { (*sync.Cond)(c).Wait() } func (c *CondImpl) WaitOrTimeout(timeout time.Duration) bool { done := make(chan struct{}) go func() { c.L.Lock() defer c.L.Unlock() c.Wait() close(done) }() select { case <-time.After(timeout): return false case <-done: return true } }