File tree Expand file tree Collapse file tree 1 file changed +54
-0
lines changed Expand file tree Collapse file tree 1 file changed +54
-0
lines changed Original file line number Diff line number Diff line change 1+ package sync
2+
3+ import "internal/task"
4+
5+ type WaitGroup struct {
6+ counter uint
7+ waiters task.Stack
8+ }
9+
10+ func (wg * WaitGroup ) Add (delta int ) {
11+ if delta > 0 {
12+ // Check for overflow.
13+ if uint (delta ) > (^ uint (0 ))- wg .counter {
14+ panic ("sync: WaitGroup counter overflowed" )
15+ }
16+
17+ // Add to the counter.
18+ wg .counter += uint (delta )
19+ } else {
20+ // Check for underflow.
21+ if uint (- delta ) > wg .counter {
22+ panic ("sync: negative WaitGroup counter" )
23+ }
24+
25+ // Subtract from the counter.
26+ wg .counter -= uint (- delta )
27+
28+ // If the counter is zero, everything is done and the waiters should be resumed.
29+ // This code assumes that the waiters cannot wake up until after this function returns.
30+ // In the current implementation, this is always correct.
31+ if wg .counter == 0 {
32+ for t := wg .waiters .Pop (); t != nil ; t = wg .waiters .Pop () {
33+ scheduleTask (t )
34+ }
35+ }
36+ }
37+ }
38+
39+ func (wg * WaitGroup ) Done () {
40+ wg .Add (- 1 )
41+ }
42+
43+ func (wg * WaitGroup ) Wait () {
44+ if wg .counter == 0 {
45+ // Everything already finished.
46+ return
47+ }
48+
49+ // Push the current goroutine onto the waiter stack.
50+ wg .waiters .Push (task .Current ())
51+
52+ // Pause until the waiters are awoken by Add/Done.
53+ task .Pause ()
54+ }
You can’t perform that action at this time.
0 commit comments