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  }