once.go (946B)
1 package errors 2 3 import ( 4 "sync/atomic" 5 "unsafe" 6 ) 7 8 // OnceError is an error structure that supports safe multi 9 // threaded usage and setting only once (until reset). 10 type OnceError struct{ err unsafe.Pointer } 11 12 // NewOnce returns a new OnceError instance. 13 func NewOnce() OnceError { 14 return OnceError{ 15 err: nil, 16 } 17 } 18 19 // Store will safely set the OnceError to value, no-op if nil. 20 func (e *OnceError) Store(err error) { 21 // Nothing to do 22 if err == nil { 23 return 24 } 25 26 // Only set if not already 27 atomic.CompareAndSwapPointer( 28 &e.err, 29 nil, 30 unsafe.Pointer(&err), 31 ) 32 } 33 34 // Load will load the currently stored error. 35 func (e *OnceError) Load() error { 36 return *(*error)(atomic.LoadPointer(&e.err)) 37 } 38 39 // IsSet returns whether OnceError has been set. 40 func (e *OnceError) IsSet() bool { 41 return (atomic.LoadPointer(&e.err) != nil) 42 } 43 44 // Reset will reset the OnceError value. 45 func (e *OnceError) Reset() { 46 atomic.StorePointer(&e.err, nil) 47 }