diff options
Diffstat (limited to 'src/pkg/sync/waitgroup.go')
| -rw-r--r-- | src/pkg/sync/waitgroup.go | 86 |
1 files changed, 0 insertions, 86 deletions
diff --git a/src/pkg/sync/waitgroup.go b/src/pkg/sync/waitgroup.go deleted file mode 100644 index 05478c630..000000000 --- a/src/pkg/sync/waitgroup.go +++ /dev/null @@ -1,86 +0,0 @@ -// Copyright 2011 The Go Authors. All rights reserved. -// Use of this source code is governed by a BSD-style -// license that can be found in the LICENSE file. - -package sync - -import "runtime" - -// A WaitGroup waits for a collection of goroutines to finish. -// The main goroutine calls Add to set the number of -// goroutines to wait for. Then each of the goroutines -// runs and calls Done when finished. At the same time, -// Wait can be used to block until all goroutines have finished. -// -// For example: -// -// for i := 0; i < n; i++ { -// if !condition(i) { -// continue -// } -// wg.Add(1) -// go func() { -// // Do something. -// wg.Done() -// }() -// } -// wg.Wait() -// -type WaitGroup struct { - m Mutex - counter int - waiters int - sema *uint32 -} - -// WaitGroup creates a new semaphore each time the old semaphore -// is released. This is to avoid the following race: -// -// G1: Add(1) -// G1: go G2() -// G1: Wait() // Context switch after Unlock() and before Semacquire(). -// G2: Done() // Release semaphore: sema == 1, waiters == 0. G1 doesn't run yet. -// G3: Wait() // Finds counter == 0, waiters == 0, doesn't block. -// G3: Add(1) // Makes counter == 1, waiters == 0. -// G3: go G4() -// G3: Wait() // G1 still hasn't run, G3 finds sema == 1, unblocked! Bug. - -// Add adds delta, which may be negative, to the WaitGroup counter. -// If the counter becomes zero, all goroutines blocked on Wait() are released. -func (wg *WaitGroup) Add(delta int) { - wg.m.Lock() - if delta < -wg.counter { - wg.m.Unlock() - panic("sync: negative WaitGroup count") - } - wg.counter += delta - if wg.counter == 0 && wg.waiters > 0 { - for i := 0; i < wg.waiters; i++ { - runtime.Semrelease(wg.sema) - } - wg.waiters = 0 - wg.sema = nil - } - wg.m.Unlock() -} - -// Done decrements the WaitGroup counter. -func (wg *WaitGroup) Done() { - wg.Add(-1) -} - -// Wait blocks until the WaitGroup counter is zero. -func (wg *WaitGroup) Wait() { - wg.m.Lock() - if wg.counter == 0 { - wg.m.Unlock() - return - } - wg.waiters++ - if wg.sema == nil { - wg.sema = new(uint32) - } - s := wg.sema - wg.m.Unlock() - runtime.Semacquire(s) -} |
