gitee.com/sy_183/go-common@v1.0.5-0.20231205030221-958cfe129b47/component/atomic-pointer.go (about)

     1  package component
     2  
     3  import (
     4  	"sync"
     5  	"sync/atomic"
     6  	"unsafe"
     7  )
     8  
     9  type AtomicPointer[E any] struct {
    10  	Init        func() *E
    11  	initializer sync.Once
    12  	elem        unsafe.Pointer
    13  }
    14  
    15  func NewAtomicPointer[E any](init func() *E) *AtomicPointer[E] {
    16  	return &AtomicPointer[E]{Init: init}
    17  }
    18  
    19  func (p *AtomicPointer[E]) store(e *E) {
    20  	atomic.StorePointer(&p.elem, unsafe.Pointer(e))
    21  }
    22  
    23  func (p *AtomicPointer[E]) load() *E {
    24  	return (*E)(atomic.LoadPointer(&p.elem))
    25  }
    26  
    27  func (p *AtomicPointer[E]) Get() *E {
    28  	if ep := p.load(); ep != nil {
    29  		return ep
    30  	}
    31  	p.initializer.Do(func() {
    32  		p.store(p.Init())
    33  	})
    34  	return p.load()
    35  }
    36  
    37  func (p *AtomicPointer[E]) Set(e *E) {
    38  	p.store(e)
    39  }