50 lines
889 B
Go
50 lines
889 B
Go
|
package analyze
|
||
|
|
||
|
import "sync"
|
||
|
|
||
|
// A WaitGroup waits for a collection of goroutines to finish.
|
||
|
// In contrast to sync.WaitGroup Add method can be called from a goroutine.
|
||
|
type WaitGroup struct {
|
||
|
wait sync.Mutex
|
||
|
value int
|
||
|
access sync.Mutex
|
||
|
}
|
||
|
|
||
|
// Init prepares the WaitGroup for usage, locks
|
||
|
func (s *WaitGroup) Init() *WaitGroup {
|
||
|
s.wait.Lock()
|
||
|
return s
|
||
|
}
|
||
|
|
||
|
// Add increments value
|
||
|
func (s *WaitGroup) Add(value int) {
|
||
|
s.access.Lock()
|
||
|
s.value += value
|
||
|
s.access.Unlock()
|
||
|
}
|
||
|
|
||
|
// Done decrements the value by one, if value is 0, lock is released
|
||
|
func (s *WaitGroup) Done() {
|
||
|
s.access.Lock()
|
||
|
s.value--
|
||
|
s.check()
|
||
|
s.access.Unlock()
|
||
|
}
|
||
|
|
||
|
// Wait blocks until value is 0
|
||
|
func (s *WaitGroup) Wait() {
|
||
|
s.access.Lock()
|
||
|
isValue := s.value > 0
|
||
|
s.access.Unlock()
|
||
|
if isValue {
|
||
|
s.wait.Lock()
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func (s *WaitGroup) check() {
|
||
|
if s.value == 0 {
|
||
|
s.wait.TryLock()
|
||
|
s.wait.Unlock()
|
||
|
}
|
||
|
}
|