set-once.go 836 B

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. package chansync
  2. import (
  3. "sync"
  4. "sync/atomic"
  5. "github.com/anacrolix/chansync/events"
  6. )
  7. // SetOnce is a boolean value that can only be flipped from false to true.
  8. type SetOnce struct {
  9. ch chan struct{}
  10. // Could be faster than trying to receive from ch
  11. closed uint32
  12. initOnce sync.Once
  13. closeOnce sync.Once
  14. }
  15. // Returns a channel that is closed when the event is flagged.
  16. func (me *SetOnce) Done() events.Done {
  17. me.init()
  18. return me.ch
  19. }
  20. func (me *SetOnce) init() {
  21. me.initOnce.Do(func() {
  22. me.ch = make(chan struct{})
  23. })
  24. }
  25. // Set only returns true the first time it is called.
  26. func (me *SetOnce) Set() (first bool) {
  27. me.closeOnce.Do(func() {
  28. me.init()
  29. first = true
  30. atomic.StoreUint32(&me.closed, 1)
  31. close(me.ch)
  32. })
  33. return
  34. }
  35. func (me *SetOnce) IsSet() bool {
  36. return atomic.LoadUint32(&me.closed) != 0
  37. }