summaryrefslogtreecommitdiff
path: root/daemon/stop.go
diff options
context:
space:
mode:
authorJosh Hawn <josh.hawn@docker.com>2017-03-30 13:52:40 -0700
committerJosh Hawn <josh.hawn@docker.com>2017-05-16 15:09:14 -0700
commitcfdf84d5d04c8ee656e5c4ad3db993c258e52674 (patch)
treebef44fcea8cce53e22286437fdb550f6e9fa06ca /daemon/stop.go
parent1290ec2d4b3611293cd993cd12fd9e78e268e296 (diff)
downloaddocker-cfdf84d5d04c8ee656e5c4ad3db993c258e52674.tar.gz
Update Container Wait Backend
This patch consolidates the two WaitStop and WaitWithContext methods on the container.State type. Now there is a single method, Wait, which takes a context and a bool specifying whether to wait for not just a container exit but also removal. The behavior has been changed slightly so that a wait call during a Created state will not return immediately but instead wait for the container to be started and then exited. The interface has been changed to no longer block, but instead returns a channel on which the caller can receive a *StateStatus value which indicates the ExitCode or an error if there was one (like a context timeout or state transition error). These changes have been propagated through the rest of the deamon to preserve all other existing behavior. Docker-DCO-1.1-Signed-off-by: Josh Hawn <josh.hawn@docker.com> (github: jlhawn)
Diffstat (limited to 'daemon/stop.go')
-rw-r--r--daemon/stop.go14
1 files changed, 11 insertions, 3 deletions
diff --git a/daemon/stop.go b/daemon/stop.go
index a17e8c8dde..4fd1e40c1e 100644
--- a/daemon/stop.go
+++ b/daemon/stop.go
@@ -1,6 +1,7 @@
package daemon
import (
+ "context"
"fmt"
"net/http"
"time"
@@ -60,7 +61,10 @@ func (daemon *Daemon) containerStop(container *container.Container, seconds int)
// So, instead we'll give it up to 2 more seconds to complete and if
// by that time the container is still running, then the error
// we got is probably valid and so we force kill it.
- if _, err := container.WaitStop(2 * time.Second); err != nil {
+ ctx, cancel := context.WithTimeout(context.Background(), 2*time.Second)
+ defer cancel()
+
+ if status := <-container.Wait(ctx, false); status.Err() != nil {
logrus.Infof("Container failed to stop after sending signal %d to the process, force killing", stopSignal)
if err := daemon.killPossiblyDeadProcess(container, 9); err != nil {
return err
@@ -69,11 +73,15 @@ func (daemon *Daemon) containerStop(container *container.Container, seconds int)
}
// 2. Wait for the process to exit on its own
- if _, err := container.WaitStop(time.Duration(seconds) * time.Second); err != nil {
+ ctx, cancel := context.WithTimeout(context.Background(), time.Duration(seconds)*time.Second)
+ defer cancel()
+
+ if status := <-container.Wait(ctx, false); status.Err() != nil {
logrus.Infof("Container %v failed to exit within %d seconds of signal %d - using the force", container.ID, seconds, stopSignal)
// 3. If it doesn't, then send SIGKILL
if err := daemon.Kill(container); err != nil {
- container.WaitStop(-1 * time.Second)
+ // Wait without a timeout, ignore result.
+ _ = <-container.Wait(context.Background(), false)
logrus.Warn(err) // Don't return error because we only care that container is stopped, not what function stopped it
}
}