package lock import ( "sync" "sync/atomic" ) var _ Locker = (*locker)(nil) type Locker interface { condition() bool Lock() Unlock() } type locker struct { lock *sync.Mutex cond *sync.Cond v *atomic.Bool } func NewLocker() Locker { lock := new(sync.Mutex) return &locker{ lock: lock, cond: sync.NewCond(lock), v: new(atomic.Bool), } } func (l *locker) condition() bool { return l.v.Load() } func (l *locker) Lock() { l.cond.L.Lock() for l.condition() { l.cond.Wait() } l.v.Store(true) } func (l *locker) Unlock() { l.v.Store(false) l.cond.L.Unlock() l.cond.Signal() }