github.com/ydb-platform/ydb-go-sdk/v3@v3.57.0/internal/xsync/event_broadcast.go (about)

     1  package xsync
     2  
     3  import (
     4  	"sync"
     5  
     6  	"github.com/ydb-platform/ydb-go-sdk/v3/internal/empty"
     7  )
     8  
     9  // EventBroadcast is implementation of broadcast notify about event
    10  // Zero value is usable, must not copy after first call any method
    11  type EventBroadcast struct {
    12  	m sync.Mutex
    13  
    14  	nextEventChannel empty.Chan
    15  }
    16  
    17  func (b *EventBroadcast) initNeedLock() {
    18  	if b.nextEventChannel == nil {
    19  		b.nextEventChannel = make(empty.Chan)
    20  	}
    21  }
    22  
    23  // Waiter return channel, that will close when next event will be broadcast.
    24  // For prevent race between subscribe and event client code must subscribe at first, then check condition
    25  // if false - wait closing channed and check condition again
    26  func (b *EventBroadcast) Waiter() OneTimeWaiter {
    27  	b.m.Lock()
    28  	defer b.m.Unlock()
    29  
    30  	b.initNeedLock()
    31  
    32  	return OneTimeWaiter{b.nextEventChannel}
    33  }
    34  
    35  func (b *EventBroadcast) Broadcast() {
    36  	b.m.Lock()
    37  	defer b.m.Unlock()
    38  
    39  	b.initNeedLock()
    40  
    41  	close(b.nextEventChannel)
    42  	b.nextEventChannel = make(empty.Chan)
    43  }
    44  
    45  type OneTimeWaiter struct {
    46  	ch empty.Chan
    47  }
    48  
    49  func (w *OneTimeWaiter) Done() <-chan struct{} {
    50  	return w.ch
    51  }