Merge pull request #37 from thekondor/1.8.1-fix-group-wait-race
Synchronize read & write of `TaskGroupWithContext`'s `err` variable
This commit is contained in:
@@ -32,10 +32,14 @@ func (g *TaskGroup) Wait() {
|
|||||||
// TaskGroupWithContext represents a group of related tasks associated to a context
|
// TaskGroupWithContext represents a group of related tasks associated to a context
|
||||||
type TaskGroupWithContext struct {
|
type TaskGroupWithContext struct {
|
||||||
TaskGroup
|
TaskGroup
|
||||||
ctx context.Context
|
ctx context.Context
|
||||||
cancel context.CancelFunc
|
cancel context.CancelFunc
|
||||||
errOnce sync.Once
|
|
||||||
err error
|
errSync struct {
|
||||||
|
once sync.Once
|
||||||
|
guard sync.RWMutex
|
||||||
|
}
|
||||||
|
err error
|
||||||
}
|
}
|
||||||
|
|
||||||
// Submit adds a task to this group and sends it to the worker pool to be executed
|
// Submit adds a task to this group and sends it to the worker pool to be executed
|
||||||
@@ -57,8 +61,11 @@ func (g *TaskGroupWithContext) Submit(task func() error) {
|
|||||||
// don't actually ignore errors
|
// don't actually ignore errors
|
||||||
err := task()
|
err := task()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
g.errOnce.Do(func() {
|
g.errSync.once.Do(func() {
|
||||||
|
g.errSync.guard.Lock()
|
||||||
g.err = err
|
g.err = err
|
||||||
|
g.errSync.guard.Unlock()
|
||||||
|
|
||||||
if g.cancel != nil {
|
if g.cancel != nil {
|
||||||
g.cancel()
|
g.cancel()
|
||||||
}
|
}
|
||||||
@@ -86,5 +93,9 @@ func (g *TaskGroupWithContext) Wait() error {
|
|||||||
case <-g.ctx.Done():
|
case <-g.ctx.Done():
|
||||||
}
|
}
|
||||||
|
|
||||||
return g.err
|
g.errSync.guard.RLock()
|
||||||
|
err := g.err
|
||||||
|
g.errSync.guard.RUnlock()
|
||||||
|
|
||||||
|
return err
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user