func (cond *TimeoutCond) Signal() {
	cond.condL.RLock()
	select {
	case cond.signal <- 1:
	default:
	}
	cond.condL.RUnlock()
}
Signal wakes one goroutine waiting on c, if there is any.
package concurrent
import (
	"context"
	"math"
	"strconv"
	"sync"
	"sync/atomic"
)
type TimeoutCond struct {
	hasWaiters uint64
	L          sync.Locker
	signal     chan int
	condL      sync.RWMutex
}
func NewTimeoutCond(l sync.Locker) *TimeoutCond {
	cond := TimeoutCond{L: l, signal: make(chan int, 1), condL: sync.RWMutex{}}
	return &cond
}
func (cond *TimeoutCond) addWaiter() {
	v := atomic.AddUint64(&cond.hasWaiters, 1)
	if v == 0 {
		panic("too many waiters; max is " + strconv.FormatUint(math.MaxUint64, 10))
	}
}
func (cond *TimeoutCond) removeWaiter() {
	v := atomic.AddUint64(&cond.hasWaiters, ^uint64(0))
	if v == math.MaxUint64 {
		panic("removeWaiter called more than once after addWaiter")
	}
}
func (cond *TimeoutCond) HasWaiters() bool {
	return atomic.LoadUint64(&cond.hasWaiters) > 0
}
func (cond *TimeoutCond) Wait(ctx context.Context) bool {
	cond.addWaiter()
	cond.condL.RLock()
	ch := cond.signal
	cond.condL.RUnlock()
	cond.L.Unlock()
	defer cond.removeWaiter()
	defer cond.L.Lock()
	select {
	case _, ok := <-ch:
		return !ok
	case <-ctx.Done():
		return false
	}
}