github.com/GoWebProd/gip@v0.0.0-20230623090727-b60d41d5d320/cond/single.go (about) 1 package cond 2 3 import ( 4 "sync/atomic" 5 "unsafe" 6 7 "github.com/GoWebProd/gip/rtime" 8 ) 9 10 var ( 11 readyData = new(interface{}) 12 readyFlag = unsafe.Pointer(&readyData) 13 ) 14 15 type Single struct { 16 state unsafe.Pointer 17 } 18 19 func (c *Single) park(p1, p2 unsafe.Pointer) bool { 20 return atomic.CompareAndSwapPointer(&c.state, nil, p1) 21 } 22 23 func (c *Single) Wait() { 24 if atomic.LoadPointer(&c.state) != nil { 25 return 26 } 27 28 rtime.GoPark(c.park, nil, 0, 0, 1) 29 } 30 31 func (c *Single) Done() { 32 v := atomic.SwapPointer(&c.state, readyFlag) 33 if v == readyFlag || v == nil { 34 return 35 } 36 37 rtime.GoReady(v, 1) 38 }