error.go (1064B)
1 package sync 2 3 import "sync" 4 5 // OnceErr wraps the behavior of recording an error 6 // once and signal on a channel when this has occurred. 7 // Signaling is done by closing of the channel. 8 // 9 // Type is safe for concurrent usage. 10 type OnceErr struct { 11 mu sync.RWMutex 12 err error 13 ch chan struct{} 14 } 15 16 // NewOnceErr return a new OnceErr 17 func NewOnceErr() *OnceErr { 18 return &OnceErr{ 19 ch: make(chan struct{}, 1), 20 } 21 } 22 23 // Err acquires a read-lock and returns an 24 // error if one has been set. 25 func (e *OnceErr) Err() error { 26 e.mu.RLock() 27 err := e.err 28 e.mu.RUnlock() 29 30 return err 31 } 32 33 // SetError acquires a write-lock and will set 34 // the underlying error value if one has not been set. 35 func (e *OnceErr) SetError(err error) { 36 if err == nil { 37 return 38 } 39 40 e.mu.Lock() 41 if e.err == nil { 42 e.err = err 43 close(e.ch) 44 } 45 e.mu.Unlock() 46 } 47 48 // ErrorSet returns a channel that will be used to signal 49 // that an error has been set. This channel will be closed 50 // when the error value has been set for OnceErr. 51 func (e *OnceErr) ErrorSet() <-chan struct{} { 52 return e.ch 53 }