From b06311a72e7979653f09ba8175e10733e7116985 Mon Sep 17 00:00:00 2001 From: Victor Vieux Date: Tue, 29 Jul 2014 07:14:10 +0000 Subject: [PATCH] fix goroutines leak and exit code Docker-DCO-1.1-Signed-off-by: Victor Vieux (github: vieux) Signed-off-by: Victor Vieux --- daemon/container.go | 11 +++-------- daemon/execdriver/native/init.go | 1 + daemon/state.go | 30 +++++++++++++----------------- 3 files changed, 17 insertions(+), 25 deletions(-) diff --git a/daemon/container.go b/daemon/container.go index 68ab5ae281..8f0b0480aa 100644 --- a/daemon/container.go +++ b/daemon/container.go @@ -1111,6 +1111,7 @@ func (container *Container) startLoggingToDisk() error { } func (container *Container) waitForStart() error { + waitStart := make(chan struct{}) callback := func(command *execdriver.Command) { if command.Tty { // The callback is called after the process Start() @@ -1121,22 +1122,16 @@ func (container *Container) waitForStart() error { } } container.State.SetRunning(command.Pid()) - if err := container.ToDisk(); err != nil { + if err := container.toDisk(); err != nil { utils.Debugf("%s", err) } + close(waitStart) } // We use a callback here instead of a goroutine and an chan for // syncronization purposes cErr := utils.Go(func() error { return container.monitor(callback) }) - waitStart := make(chan struct{}) - - go func() { - container.State.WaitRunning(-1 * time.Second) - close(waitStart) - }() - // Start should not return until the process is actually running select { case <-waitStart: diff --git a/daemon/execdriver/native/init.go b/daemon/execdriver/native/init.go index 5661454162..75b8aebfd9 100644 --- a/daemon/execdriver/native/init.go +++ b/daemon/execdriver/native/init.go @@ -62,4 +62,5 @@ func initializer() { func writeError(err error) { fmt.Sprint(os.Stderr, err) + os.Exit(1) } diff --git a/daemon/state.go b/daemon/state.go index e500d735e3..9baa396843 100644 --- a/daemon/state.go +++ b/daemon/state.go @@ -114,28 +114,24 @@ func (s *State) GetExitCode() int { func (s *State) SetRunning(pid int) { s.Lock() - if !s.Running { - s.Running = true - s.Paused = false - s.ExitCode = 0 - s.Pid = pid - s.StartedAt = time.Now().UTC() - close(s.waitChan) // fire waiters for start - s.waitChan = make(chan struct{}) - } + s.Running = true + s.Paused = false + s.ExitCode = 0 + s.Pid = pid + s.StartedAt = time.Now().UTC() + close(s.waitChan) // fire waiters for start + s.waitChan = make(chan struct{}) s.Unlock() } func (s *State) SetStopped(exitCode int) { s.Lock() - if s.Running { - s.Running = false - s.Pid = 0 - s.FinishedAt = time.Now().UTC() - s.ExitCode = exitCode - close(s.waitChan) // fire waiters for stop - s.waitChan = make(chan struct{}) - } + s.Running = false + s.Pid = 0 + s.FinishedAt = time.Now().UTC() + s.ExitCode = exitCode + close(s.waitChan) // fire waiters for stop + s.waitChan = make(chan struct{}) s.Unlock() }