Stop holding container lock while waiting on streams
Signed-off-by: Darren Stahl <darst@microsoft.com>
This commit is contained in:
parent
f81c538fec
commit
07cd19655b
|
@ -82,10 +82,10 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
|
||||||
}
|
}
|
||||||
return daemon.postRunProcessing(c, e)
|
return daemon.postRunProcessing(c, e)
|
||||||
case libcontainerd.StateExitProcess:
|
case libcontainerd.StateExitProcess:
|
||||||
c.Lock()
|
|
||||||
defer c.Unlock()
|
|
||||||
if execConfig := c.ExecCommands.Get(e.ProcessID); execConfig != nil {
|
if execConfig := c.ExecCommands.Get(e.ProcessID); execConfig != nil {
|
||||||
ec := int(e.ExitCode)
|
ec := int(e.ExitCode)
|
||||||
|
execConfig.Lock()
|
||||||
|
defer execConfig.Unlock()
|
||||||
execConfig.ExitCode = &ec
|
execConfig.ExitCode = &ec
|
||||||
execConfig.Running = false
|
execConfig.Running = false
|
||||||
execConfig.Wait()
|
execConfig.Wait()
|
||||||
|
|
|
@ -539,3 +539,63 @@ func (s *DockerSuite) TestExecEnvLinksHost(c *check.C) {
|
||||||
c.Assert(out, checker.Contains, "HOSTNAME=myhost")
|
c.Assert(out, checker.Contains, "HOSTNAME=myhost")
|
||||||
c.Assert(out, checker.Contains, "DB_NAME=/bar/db")
|
c.Assert(out, checker.Contains, "DB_NAME=/bar/db")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (s *DockerSuite) TestExecWindowsOpenHandles(c *check.C) {
|
||||||
|
testRequires(c, DaemonIsWindows)
|
||||||
|
runSleepingContainer(c, "-d", "--name", "test")
|
||||||
|
exec := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
dockerCmd(c, "exec", "test", "cmd", "/c", "start sleep 10")
|
||||||
|
exec <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
for {
|
||||||
|
top := make(chan string)
|
||||||
|
var out string
|
||||||
|
go func() {
|
||||||
|
out, _ := dockerCmd(c, "top", "test")
|
||||||
|
top <- out
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(time.Second * 5):
|
||||||
|
c.Error("timed out waiting for top while exec is exiting")
|
||||||
|
case out = <-top:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
if strings.Count(out, "busybox.exe") == 2 && !strings.Contains(out, "cmd.exe") {
|
||||||
|
// The initial exec process (cmd.exe) has exited, and both sleeps are currently running
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(1 * time.Second)
|
||||||
|
}
|
||||||
|
|
||||||
|
inspect := make(chan bool)
|
||||||
|
go func() {
|
||||||
|
dockerCmd(c, "inspect", "test")
|
||||||
|
inspect <- true
|
||||||
|
}()
|
||||||
|
|
||||||
|
select {
|
||||||
|
case <-time.After(time.Second * 5):
|
||||||
|
c.Error("timed out waiting for inspect while exec is exiting")
|
||||||
|
case <-inspect:
|
||||||
|
break
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure the background sleep is still running
|
||||||
|
out, _ := dockerCmd(c, "top", "test")
|
||||||
|
c.Assert(strings.Count(out, "busybox.exe"), checker.Equals, 2)
|
||||||
|
|
||||||
|
// The exec should exit when the background sleep exits
|
||||||
|
select {
|
||||||
|
case <-time.After(time.Second * 15):
|
||||||
|
c.Error("timed out waiting for async exec to exit")
|
||||||
|
case <-exec:
|
||||||
|
// Ensure the background sleep has actually exited
|
||||||
|
out, _ := dockerCmd(c, "top", "test")
|
||||||
|
c.Assert(strings.Count(out, "busybox.exe"), checker.Equals, 1)
|
||||||
|
break
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue