error.go 1.0 KB

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