diff options
Diffstat (limited to 'libgo/go/sync/waitgroup.go')
-rw-r--r-- | libgo/go/sync/waitgroup.go | 21 |
1 files changed, 13 insertions, 8 deletions
diff --git a/libgo/go/sync/waitgroup.go b/libgo/go/sync/waitgroup.go index 22681115cb..92cc57d2cc 100644 --- a/libgo/go/sync/waitgroup.go +++ b/libgo/go/sync/waitgroup.go @@ -37,10 +37,13 @@ type WaitGroup struct { // If the counter becomes zero, all goroutines blocked on Wait are released. // If the counter goes negative, Add panics. // -// Note that calls with positive delta must happen before the call to Wait, -// or else Wait may wait for too small a group. Typically this means the calls -// to Add should execute before the statement creating the goroutine or -// other event to be waited for. See the WaitGroup example. +// Note that calls with a positive delta that occur when the counter is zero +// must happen before a Wait. Calls with a negative delta, or calls with a +// positive delta that start when the counter is greater than zero, may happen +// at any time. +// Typically this means the calls to Add should execute before the statement +// creating the goroutine or other event to be waited for. +// See the WaitGroup example. func (wg *WaitGroup) Add(delta int) { if raceenabled { _ = wg.m.state // trigger nil deref early @@ -67,11 +70,13 @@ func (wg *WaitGroup) Add(delta int) { return } wg.m.Lock() - for i := int32(0); i < wg.waiters; i++ { - runtime_Semrelease(wg.sema) + if atomic.LoadInt32(&wg.counter) == 0 { + for i := int32(0); i < wg.waiters; i++ { + runtime_Semrelease(wg.sema) + } + wg.waiters = 0 + wg.sema = nil } - wg.waiters = 0 - wg.sema = nil wg.m.Unlock() } |