github.com/omniscale/go-osm@v0.3.1/parser/pbf/barrier.go (about) 1 package pbf 2 3 import ( 4 "sync" 5 "sync/atomic" 6 ) 7 8 // barrier is a struct to synchronize multiple goroutines. 9 // Works similar to a WaitGroup. Except: 10 // Calls callback function once all goroutines called doneWait(). 11 // doneWait() blocks until the callback returns. doneWait() does not 12 // block after all goroutines were blocked once. 13 type barrier struct { 14 synced int32 15 wg sync.WaitGroup 16 once sync.Once 17 callbackWg sync.WaitGroup 18 callback func() 19 } 20 21 func newBarrier(callback func()) *barrier { 22 s := &barrier{callback: callback} 23 s.callbackWg.Add(1) 24 return s 25 } 26 27 func (s *barrier) add(delta int) { 28 s.wg.Add(delta) 29 } 30 31 func (s *barrier) doneWait() { 32 if atomic.LoadInt32(&s.synced) == 1 { 33 return 34 } 35 s.wg.Done() 36 s.wg.Wait() 37 s.once.Do(s.call) 38 s.callbackWg.Wait() 39 } 40 41 func (s *barrier) call() { 42 s.callback() 43 atomic.StoreInt32(&s.synced, 1) 44 s.callbackWg.Done() 45 }