aboutsummaryrefslogtreecommitdiffstats
path: root/layout/waitgroup.go
blob: e32b350cd1b03e6bf75a7dcaaa0ea22ec3960812 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
package layout

// WaitGroup is a counting semaphore used to wait for a group of goroutines to finish.
// It differs from sync/WaitGroup in that Wait() is a channel rather than a blocking function.
type waitgroup struct {
	done    chan<- struct{}
	alldone <-chan struct{}
}

// NewWaitGroup creates a group of n goroutines: a semaphore with a capacity of n.
func newWaitGroup(n uint) waitgroup {
	done, alldone := make(chan struct{}), make(chan struct{})
	go func() {
		for ; n > 0; n-- {
			<-done
		}
		alldone <- *new(struct{})
		close(done)
		close(alldone)
	}()
	return waitgroup{done, alldone}
}

// Done decrements the task counter by one.
func (wg waitgroup) Done() {
	wg.done <- *new(struct{})
}

// Wait returns a channel that blocks until the task counter is zero.
func (wg waitgroup) Wait() <-chan struct{} {
	return wg.alldone
}