github.com/godaddy-x/freego@v1.0.156/utils/concurrent/once.go (about)

     1  package concurrent
     2  
     3  import (
     4  	"sync"
     5  	"sync/atomic"
     6  )
     7  
     8  type Once struct {
     9  	done uint32
    10  	m    sync.Mutex
    11  }
    12  
    13  func (o *Once) Do(f func() (interface{}, error)) (interface{}, error) {
    14  	if atomic.LoadUint32(&o.done) == 0 {
    15  		return o.doSlow(f)
    16  	}
    17  	return nil, nil
    18  }
    19  
    20  func (o *Once) doSlow(f func() (interface{}, error)) (interface{}, error) {
    21  	o.m.Lock()
    22  	defer o.m.Unlock()
    23  	if o.done == 0 {
    24  		defer atomic.StoreUint32(&o.done, 1)
    25  		return f()
    26  	}
    27  	return nil, nil
    28  }