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 int32 } func NewLocker() Locker { lock := new(sync.Mutex) return &locker{ lock: lock, cond: sync.NewCond(lock), v: 0, } } func (l *locker) condition() bool { return atomic.LoadInt32(&l.v) == 1 } func (l *locker) Lock() { l.cond.L.Lock() for l.condition() { l.cond.Wait() } atomic.StoreInt32(&l.v, 1) } func (l *locker) Unlock() { atomic.StoreInt32(&l.v, 0) l.cond.L.Unlock() l.cond.Signal() }