Merge pull request #28682 from tonistiigi/stdin-close

Fix race on sending stdin close event
This commit is contained in:
Justin Cormack 2016-11-22 11:02:47 +00:00 committed by GitHub
commit 3373227f36
2 changed files with 35 additions and 1 deletions

View file

@ -5,6 +5,7 @@ import (
"bytes"
"encoding/json"
"fmt"
"io"
"io/ioutil"
"net"
"os"
@ -4849,3 +4850,32 @@ func (s *DockerSuite) TestRunEmptyEnv(c *check.C) {
c.Assert(err, checker.NotNil)
c.Assert(out, checker.Contains, expectedOutput)
}
// #28658
func (s *DockerSuite) TestSlowStdinClosing(c *check.C) {
name := "testslowstdinclosing"
repeat := 3 // regression happened 50% of the time
for i := 0; i < repeat; i++ {
cmd := exec.Command(dockerBinary, "run", "--rm", "--name", name, "-i", "busybox", "cat")
cmd.Stdin = &delayedReader{}
done := make(chan error, 1)
go func() {
_, err := runCommand(cmd)
done <- err
}()
select {
case <-time.After(15 * time.Second):
c.Fatal("running container timed out") // cleanup in teardown
case err := <-done:
c.Assert(err, checker.IsNil)
}
}
}
type delayedReader struct{}
func (s *delayedReader) Read([]byte) (int, error) {
time.Sleep(500 * time.Millisecond)
return 0, io.EOF
}

View file

@ -116,12 +116,16 @@ func (ctr *container) start(checkpoint string, checkpointDir string, attachStdio
stdinOnce.Do(func() { // on error from attach we don't know if stdin was already closed
err = stdin.Close()
go func() {
select {
case <-ready:
case <-ctx.Done():
}
select {
case <-ready:
if err := ctr.sendCloseStdin(); err != nil {
logrus.Warnf("failed to close stdin: %+v", err)
}
case <-ctx.Done():
default:
}
}()
})