github.com/sandwich-go/boost@v1.3.29/xsync/cond.go (about) 1 package xsync 2 3 import ( 4 "sync" 5 ) 6 7 // Cond is an alternate implementation of sync.Cond 8 type Cond struct { 9 L sync.Locker 10 sema chan struct{} 11 waiters AtomicInt64 12 } 13 14 func NewCond(l sync.Locker) *Cond { 15 return &Cond{L: l, sema: make(chan struct{})} 16 } 17 18 func (c *Cond) Wait() { 19 c.waiters.Add(1) 20 c.L.Unlock() 21 <-c.sema 22 c.L.Lock() 23 } 24 25 func (c *Cond) Signal() { 26 for { 27 w := c.waiters.Get() 28 if w == 0 { 29 return 30 } 31 if c.waiters.CompareAndSwap(w, w-1) { 32 break 33 } 34 } 35 c.sema <- struct{}{} 36 } 37 38 func (c *Cond) Broadcast() { 39 var w int64 40 for { 41 w = c.waiters.Get() 42 if w == 0 { 43 return 44 } 45 if c.waiters.CompareAndSwap(w, 0) { 46 break 47 } 48 } 49 for i := int64(0); i < w; i++ { 50 c.sema <- struct{}{} 51 } 52 }