Sfoglia il codice sorgente

Stop holding container lock while waiting on streams

Signed-off-by: Darren Stahl <darst@microsoft.com>
Darren Stahl 8 anni fa
parent
commit
07cd19655b
2 ha cambiato i file con 62 aggiunte e 2 eliminazioni
  1. 2 2
      daemon/monitor.go
  2. 60 0
      integration-cli/docker_cli_exec_test.go

+ 2 - 2
daemon/monitor.go

@@ -82,10 +82,10 @@ func (daemon *Daemon) StateChanged(id string, e libcontainerd.StateInfo) error {
 		}
 		return daemon.postRunProcessing(c, e)
 	case libcontainerd.StateExitProcess:
-		c.Lock()
-		defer c.Unlock()
 		if execConfig := c.ExecCommands.Get(e.ProcessID); execConfig != nil {
 			ec := int(e.ExitCode)
+			execConfig.Lock()
+			defer execConfig.Unlock()
 			execConfig.ExitCode = &ec
 			execConfig.Running = false
 			execConfig.Wait()

+ 60 - 0
integration-cli/docker_cli_exec_test.go

@@ -539,3 +539,63 @@ func (s *DockerSuite) TestExecEnvLinksHost(c *check.C) {
 	c.Assert(out, checker.Contains, "HOSTNAME=myhost")
 	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
+	}
+}