You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
52 lines
1.4 KiB
52 lines
1.4 KiB
package conc |
|
|
|
import ( |
|
"sync" |
|
|
|
"github.com/sourcegraph/conc/panics" |
|
) |
|
|
|
// NewWaitGroup creates a new WaitGroup. |
|
func NewWaitGroup() *WaitGroup { |
|
return &WaitGroup{} |
|
} |
|
|
|
// WaitGroup is the primary building block for scoped concurrency. |
|
// Goroutines can be spawned in the WaitGroup with the Go method, |
|
// and calling Wait() will ensure that each of those goroutines exits |
|
// before continuing. Any panics in a child goroutine will be caught |
|
// and propagated to the caller of Wait(). |
|
// |
|
// The zero value of WaitGroup is usable, just like sync.WaitGroup. |
|
// Also like sync.WaitGroup, it must not be copied after first use. |
|
type WaitGroup struct { |
|
wg sync.WaitGroup |
|
pc panics.Catcher |
|
} |
|
|
|
// Go spawns a new goroutine in the WaitGroup. |
|
func (h *WaitGroup) Go(f func()) { |
|
h.wg.Add(1) |
|
go func() { |
|
defer h.wg.Done() |
|
h.pc.Try(f) |
|
}() |
|
} |
|
|
|
// Wait will block until all goroutines spawned with Go exit and will |
|
// propagate any panics spawned in a child goroutine. |
|
func (h *WaitGroup) Wait() { |
|
h.wg.Wait() |
|
|
|
// Propagate a panic if we caught one from a child goroutine. |
|
h.pc.Repanic() |
|
} |
|
|
|
// WaitAndRecover will block until all goroutines spawned with Go exit and |
|
// will return a *panics.Recovered if one of the child goroutines panics. |
|
func (h *WaitGroup) WaitAndRecover() *panics.Recovered { |
|
h.wg.Wait() |
|
|
|
// Return a recovered panic if we caught one from a child goroutine. |
|
return h.pc.Recovered() |
|
}
|
|
|