Merge pull request #29424 from tonistiigi/fix-sdin-close
Fix race on sending stdin close event
This commit is contained in:
commit
e9e3ab6b6a
2 changed files with 35 additions and 1 deletions
|
@ -4,6 +4,7 @@ import (
|
|||
"bufio"
|
||||
"bytes"
|
||||
"fmt"
|
||||
"io"
|
||||
"io/ioutil"
|
||||
"net"
|
||||
"os"
|
||||
|
@ -4467,3 +4468,32 @@ func (s *DockerSuite) TestRunStoppedLoggingDriverNoLeak(c *check.C) {
|
|||
// NGoroutines is not updated right away, so we need to wait before failing
|
||||
c.Assert(waitForGoroutines(nroutines), checker.IsNil)
|
||||
}
|
||||
|
||||
// #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
|
||||
}
|
||||
|
|
|
@ -115,12 +115,16 @@ func (ctr *container) start(attachStdio StdioCallback) error {
|
|||
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:
|
||||
}
|
||||
}()
|
||||
})
|
||||
|
|
Loading…
Reference in a new issue