70 lines
871 B
Go
70 lines
871 B
Go
package sync
|
|
|
|
import (
|
|
"context"
|
|
"sync"
|
|
)
|
|
|
|
type WaitGroup struct {
|
|
wg *sync.WaitGroup
|
|
c int
|
|
mu sync.Mutex
|
|
}
|
|
|
|
func WrapWaitGroup(wg *sync.WaitGroup) *WaitGroup {
|
|
g := &WaitGroup{
|
|
wg: wg,
|
|
}
|
|
return g
|
|
}
|
|
|
|
func NewWaitGroup() *WaitGroup {
|
|
var wg sync.WaitGroup
|
|
return WrapWaitGroup(&wg)
|
|
}
|
|
|
|
func (g *WaitGroup) Add(n int) {
|
|
g.mu.Lock()
|
|
g.c += n
|
|
g.wg.Add(n)
|
|
g.mu.Unlock()
|
|
}
|
|
|
|
func (g *WaitGroup) Done() {
|
|
g.mu.Lock()
|
|
g.c += -1
|
|
g.wg.Add(-1)
|
|
g.mu.Unlock()
|
|
}
|
|
|
|
func (g *WaitGroup) Wait() {
|
|
g.wg.Wait()
|
|
}
|
|
|
|
func (g *WaitGroup) WaitContext(ctx context.Context) {
|
|
done := make(chan struct{})
|
|
go func() {
|
|
g.wg.Wait()
|
|
close(done)
|
|
}()
|
|
|
|
select {
|
|
case <-ctx.Done():
|
|
g.mu.Lock()
|
|
g.wg.Add(-g.c)
|
|
<-done
|
|
g.wg.Add(g.c)
|
|
g.mu.Unlock()
|
|
return
|
|
case <-done:
|
|
return
|
|
}
|
|
}
|
|
|
|
func (g *WaitGroup) Waiters() int {
|
|
g.mu.Lock()
|
|
c := g.c
|
|
g.mu.Unlock()
|
|
return c
|
|
}
|