Skip to content

Commit c85fe2d

Browse files
authored
Merge pull request moby#38522 from cpuguy83/fix_timers
Make sure timers are stopped after use.
2 parents 1d5748d + eaad3ee commit c85fe2d

File tree

15 files changed

+120
-40
lines changed

15 files changed

+120
-40
lines changed

api/server/router/system/system_routes.go

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -174,7 +174,9 @@ func (s *systemRouter) getEvents(ctx context.Context, w http.ResponseWriter, r *
174174

175175
if !onlyPastEvents {
176176
dur := until.Sub(now)
177-
timeout = time.After(dur)
177+
timer := time.NewTimer(dur)
178+
defer timer.Stop()
179+
timeout = timer.C
178180
}
179181
}
180182

cmd/dockerd/daemon.go

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -400,10 +400,14 @@ func shutdownDaemon(d *daemon.Daemon) {
400400
logrus.Debug("Clean shutdown succeeded")
401401
return
402402
}
403+
404+
timeout := time.NewTimer(time.Duration(shutdownTimeout) * time.Second)
405+
defer timeout.Stop()
406+
403407
select {
404408
case <-ch:
405409
logrus.Debug("Clean shutdown succeeded")
406-
case <-time.After(time.Duration(shutdownTimeout) * time.Second):
410+
case <-timeout.C:
407411
logrus.Error("Force shutdown daemon")
408412
}
409413
}

container/monitor.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,11 @@ func (container *Container) Reset(lock bool) {
3333
container.LogCopier.Wait()
3434
close(exit)
3535
}()
36+
37+
timer := time.NewTimer(loggerCloseTimeout)
38+
defer timer.Stop()
3639
select {
37-
case <-time.After(loggerCloseTimeout):
40+
case <-timer.C:
3841
logrus.Warn("Logger didn't exit in time: logs may be truncated")
3942
case <-exit:
4043
}

daemon/cluster/cluster.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -186,8 +186,11 @@ func (c *Cluster) Start() error {
186186
}
187187
c.nr = nr
188188

189+
timer := time.NewTimer(swarmConnectTimeout)
190+
defer timer.Stop()
191+
189192
select {
190-
case <-time.After(swarmConnectTimeout):
193+
case <-timer.C:
191194
logrus.Error("swarm component could not be started before timeout was reached")
192195
case err := <-nr.Ready():
193196
if err != nil {

daemon/cluster/swarm.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -194,8 +194,11 @@ func (c *Cluster) Join(req types.JoinRequest) error {
194194
c.nr = nr
195195
c.mu.Unlock()
196196

197+
timeout := time.NewTimer(swarmConnectTimeout)
198+
defer timeout.Stop()
199+
197200
select {
198-
case <-time.After(swarmConnectTimeout):
201+
case <-timeout.C:
199202
return errSwarmJoinTimeoutReached
200203
case err := <-nr.Ready():
201204
if err != nil {

daemon/daemon.go

Lines changed: 17 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -486,12 +486,14 @@ func (daemon *Daemon) restore() error {
486486
// ignore errors here as this is a best effort to wait for children to be
487487
// running before we try to start the container
488488
children := daemon.children(c)
489-
timeout := time.After(5 * time.Second)
489+
timeout := time.NewTimer(5 * time.Second)
490+
defer timeout.Stop()
491+
490492
for _, child := range children {
491493
if notifier, exists := restartContainers[child]; exists {
492494
select {
493495
case <-notifier:
494-
case <-timeout:
496+
case <-timeout.C:
495497
}
496498
}
497499
}
@@ -609,6 +611,7 @@ func (daemon *Daemon) waitForNetworks(c *container.Container) {
609611
if daemon.discoveryWatcher == nil {
610612
return
611613
}
614+
612615
// Make sure if the container has a network that requires discovery that the discovery service is available before starting
613616
for netName := range c.NetworkSettings.Networks {
614617
// If we get `ErrNoSuchNetwork` here, we can assume that it is due to discovery not being ready
@@ -617,13 +620,19 @@ func (daemon *Daemon) waitForNetworks(c *container.Container) {
617620
if _, ok := err.(libnetwork.ErrNoSuchNetwork); !ok {
618621
continue
619622
}
623+
620624
// use a longish timeout here due to some slowdowns in libnetwork if the k/v store is on anything other than --net=host
621625
// FIXME: why is this slow???
626+
dur := 60 * time.Second
627+
timer := time.NewTimer(dur)
628+
622629
logrus.Debugf("Container %s waiting for network to be ready", c.Name)
623630
select {
624631
case <-daemon.discoveryWatcher.ReadyCh():
625-
case <-time.After(60 * time.Second):
632+
case <-timer.C:
626633
}
634+
timer.Stop()
635+
627636
return
628637
}
629638
}
@@ -673,10 +682,14 @@ func (daemon *Daemon) DaemonLeavesCluster() {
673682
// This is called also on graceful daemon shutdown. We need to
674683
// wait, because the ingress release has to happen before the
675684
// network controller is stopped.
685+
676686
if done, err := daemon.ReleaseIngress(); err == nil {
687+
timeout := time.NewTimer(5 * time.Second)
688+
defer timeout.Stop()
689+
677690
select {
678691
case <-done:
679-
case <-time.After(5 * time.Second):
692+
case <-timeout.C:
680693
logrus.Warn("timeout while waiting for ingress network removal")
681694
}
682695
} else {

daemon/discovery/discovery.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -148,12 +148,14 @@ func (d *daemonDiscoveryReloader) initHeartbeat(address string) error {
148148
// Setup a short ticker until the first heartbeat has succeeded
149149
t := time.NewTicker(500 * time.Millisecond)
150150
defer t.Stop()
151+
151152
// timeout makes sure that after a period of time we stop being so aggressive trying to reach the discovery service
152-
timeout := time.After(60 * time.Second)
153+
timeout := time.NewTimer(60 * time.Second)
154+
defer timeout.Stop()
153155

154156
for {
155157
select {
156-
case <-timeout:
158+
case <-timeout.C:
157159
return errors.New("timeout waiting for initial discovery")
158160
case <-d.term:
159161
return errors.New("terminated")

daemon/exec.go

Lines changed: 7 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@ import (
2323
)
2424

2525
// Seconds to wait after sending TERM before trying KILL
26-
const termProcessTimeout = 10
26+
const termProcessTimeout = 10 * time.Second
2727

2828
func (d *Daemon) registerExecCommand(container *container.Container, config *exec.Config) {
2929
// Storing execs in container in order to kill them gracefully whenever the container is stopped or removed.
@@ -277,9 +277,13 @@ func (d *Daemon) ContainerExecStart(ctx context.Context, name string, stdin io.R
277277
case <-ctx.Done():
278278
logrus.Debugf("Sending TERM signal to process %v in container %v", name, c.ID)
279279
d.containerd.SignalProcess(ctx, c.ID, name, int(signal.SignalMap["TERM"]))
280+
281+
timeout := time.NewTimer(termProcessTimeout)
282+
defer timeout.Stop()
283+
280284
select {
281-
case <-time.After(termProcessTimeout * time.Second):
282-
logrus.Infof("Container %v, process %v failed to exit within %d seconds of signal TERM - using the force", c.ID, name, termProcessTimeout)
285+
case <-timeout.C:
286+
logrus.Infof("Container %v, process %v failed to exit within %v of signal TERM - using the force", c.ID, name, termProcessTimeout)
283287
d.containerd.SignalProcess(ctx, c.ID, name, int(signal.SignalMap["KILL"]))
284288
case <-attachErr:
285289
// TERM signal worked

daemon/health.go

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -187,12 +187,18 @@ func handleProbeResult(d *Daemon, c *container.Container, result *types.Healthch
187187
func monitor(d *Daemon, c *container.Container, stop chan struct{}, probe probe) {
188188
probeTimeout := timeoutWithDefault(c.Config.Healthcheck.Timeout, defaultProbeTimeout)
189189
probeInterval := timeoutWithDefault(c.Config.Healthcheck.Interval, defaultProbeInterval)
190+
191+
intervalTimer := time.NewTimer(probeInterval)
192+
defer intervalTimer.Stop()
193+
190194
for {
195+
intervalTimer.Reset(probeInterval)
196+
191197
select {
192198
case <-stop:
193199
logrus.Debugf("Stop healthcheck monitoring for container %s (received while idle)", c.ID)
194200
return
195-
case <-time.After(probeInterval):
201+
case <-intervalTimer.C:
196202
logrus.Debugf("Running health check for container %s ...", c.ID)
197203
startTime := time.Now()
198204
ctx, cancelProbe := context.WithTimeout(context.Background(), probeTimeout)

daemon/resize.go

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -38,13 +38,16 @@ func (daemon *Daemon) ContainerExecResize(name string, height, width int) error
3838
if err != nil {
3939
return err
4040
}
41+
4142
// TODO: the timeout is hardcoded here, it would be more flexible to make it
4243
// a parameter in resize request context, which would need API changes.
43-
timeout := 10 * time.Second
44+
timeout := time.NewTimer(10 * time.Second)
45+
defer timeout.Stop()
46+
4447
select {
4548
case <-ec.Started:
4649
return daemon.containerd.ResizeTerminal(context.Background(), ec.ContainerID, ec.ID, width, height)
47-
case <-time.After(timeout):
50+
case <-timeout.C:
4851
return fmt.Errorf("timeout waiting for exec session ready")
4952
}
5053
}

0 commit comments

Comments
 (0)