github.com/GoWebProd/gip@v0.0.0-20230623090727-b60d41d5d320/cond/multi.go (about) 1 package cond 2 3 import ( 4 "sync" 5 "unsafe" 6 7 "github.com/GoWebProd/gip/rtime" 8 "github.com/GoWebProd/gip/stack" 9 ) 10 11 type Multi struct { 12 ready bool 13 waiters stack.MutexStack[unsafe.Pointer] 14 mu sync.Mutex 15 } 16 17 func (c *Multi) park(p1, p2 unsafe.Pointer) bool { 18 c.waiters.PushUnlocked(p1) 19 c.mu.Unlock() 20 21 return true 22 } 23 24 func (c *Multi) Wait() { 25 c.mu.Lock() 26 27 if c.ready { 28 c.mu.Unlock() 29 30 return 31 } 32 33 rtime.GoPark(c.park, unsafe.Pointer(&c.mu), 0, 0, 1) 34 } 35 36 func (c *Multi) Done() { 37 c.mu.Lock() 38 39 c.ready = true 40 41 for { 42 g, ok := c.waiters.PopUnlocked() 43 if !ok { 44 break 45 } 46 47 rtime.GoReady(g, 1) 48 } 49 50 c.mu.Unlock() 51 }