1
0
Fork 0
mirror of https://github.com/moby/moby.git synced 2022-11-09 12:21:53 -05:00

Merge pull request #26719 from AkihiroSuda/fix-race-builder-vs-container-1

Fix a race found in TestBuildCancellationKillsSleep
This commit is contained in:
Tibor Vass 2016-10-10 18:54:55 +02:00 committed by GitHub
commit f5f0b77cec

View file

@ -16,7 +16,6 @@ import (
"path/filepath" "path/filepath"
"sort" "sort"
"strings" "strings"
"sync"
"time" "time"
"github.com/Sirupsen/logrus" "github.com/Sirupsen/logrus"
@ -524,10 +523,7 @@ func (b *Builder) run(cID string) (err error) {
}() }()
finished := make(chan struct{}) finished := make(chan struct{})
var once sync.Once
finish := func() { close(finished) }
cancelErrCh := make(chan error, 1) cancelErrCh := make(chan error, 1)
defer once.Do(finish)
go func() { go func() {
select { select {
case <-b.clientCtx.Done(): case <-b.clientCtx.Done():
@ -541,22 +537,37 @@ func (b *Builder) run(cID string) (err error) {
}() }()
if err := b.docker.ContainerStart(cID, nil, true, ""); err != nil { if err := b.docker.ContainerStart(cID, nil, true, ""); err != nil {
close(finished)
if cancelErr := <-cancelErrCh; cancelErr != nil {
logrus.Debugf("Build cancelled (%v) and got an error from ContainerStart: %v",
cancelErr, err)
}
return err return err
} }
// Block on reading output from container, stop on err or chan closed // Block on reading output from container, stop on err or chan closed
if err := <-errCh; err != nil { if err := <-errCh; err != nil {
close(finished)
if cancelErr := <-cancelErrCh; cancelErr != nil {
logrus.Debugf("Build cancelled (%v) and got an error from errCh: %v",
cancelErr, err)
}
return err return err
} }
if ret, _ := b.docker.ContainerWait(cID, -1); ret != 0 { if ret, _ := b.docker.ContainerWait(cID, -1); ret != 0 {
close(finished)
if cancelErr := <-cancelErrCh; cancelErr != nil {
logrus.Debugf("Build cancelled (%v) and got a non-zero code from ContainerWait: %d",
cancelErr, ret)
}
// TODO: change error type, because jsonmessage.JSONError assumes HTTP // TODO: change error type, because jsonmessage.JSONError assumes HTTP
return &jsonmessage.JSONError{ return &jsonmessage.JSONError{
Message: fmt.Sprintf("The command '%s' returned a non-zero code: %d", strings.Join(b.runConfig.Cmd, " "), ret), Message: fmt.Sprintf("The command '%s' returned a non-zero code: %d", strings.Join(b.runConfig.Cmd, " "), ret),
Code: ret, Code: ret,
} }
} }
once.Do(finish) close(finished)
return <-cancelErrCh return <-cancelErrCh
} }