lock.go 608 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. package lock
  2. import (
  3. "sync"
  4. "sync/atomic"
  5. )
  6. var _ Locker = (*locker)(nil)
  7. type Locker interface {
  8. condition() bool
  9. Lock()
  10. Unlock()
  11. }
  12. type locker struct {
  13. lock *sync.Mutex
  14. cond *sync.Cond
  15. v *atomic.Bool
  16. }
  17. func NewLocker() Locker {
  18. lock := new(sync.Mutex)
  19. return &locker{
  20. lock: lock,
  21. cond: sync.NewCond(lock),
  22. v: new(atomic.Bool),
  23. }
  24. }
  25. func (l *locker) condition() bool {
  26. return l.v.Load()
  27. }
  28. func (l *locker) Lock() {
  29. l.cond.L.Lock()
  30. for l.condition() {
  31. l.cond.Wait()
  32. }
  33. l.v.Store(true)
  34. }
  35. func (l *locker) Unlock() {
  36. l.v.Store(false)
  37. l.cond.L.Unlock()
  38. l.cond.Signal()
  39. }