daemon/command: setupConfigReloadTrap: handle context cancellation
Pass the daemon lifecycle context to the config reload trap and stop the Unix signal handler when the context is canceled. This also unregisters the SIGHUP notification when the goroutine exits. On Windows, signal the Win32 event when the context is canceled to wake the blocking wait and allow the reload goroutine to exit. Signed-off-by: Sebastiaan van Stijn <github@gone.nl>
This commit is contained in:
3 files changed
+31
-8
No files matched your search
@@ -363,7 +363,7 @@ func (cli *daemonCLI) start(ctx context.Context) (retErr error) {
|
||||
|
||||
go d.ProcessClusterNotifications(ctx, c.GetWatchStream())
|
||||
|
||||
cli.setupConfigReloadTrap()
|
||||
cli.setupConfigReloadTrap(ctx)
|
||||
|
||||
log.G(ctx).Info("Daemon has completed initialization")
|
||||
|
||||
|
||||
@@ -58,12 +58,23 @@ func setDefaultUmask() error {
|
||||
}
|
||||
|
||||
// setupConfigReloadTrap configures the SIGHUP signal to reload the configuration.
|
||||
func (cli *daemonCLI) setupConfigReloadTrap() {
|
||||
func (cli *daemonCLI) setupConfigReloadTrap(ctx context.Context) {
|
||||
c := make(chan os.Signal, 1)
|
||||
signal.Notify(c, unix.SIGHUP)
|
||||
|
||||
go func() {
|
||||
for range c {
|
||||
cli.reloadConfig()
|
||||
defer signal.Stop(c)
|
||||
|
||||
for {
|
||||
select {
|
||||
case <-ctx.Done():
|
||||
return
|
||||
case <-c:
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
cli.reloadConfig()
|
||||
}
|
||||
}
|
||||
}()
|
||||
}
|
||||
|
||||
@@ -80,9 +80,7 @@ func notifyShutdown(ctx context.Context, err error) {
|
||||
}
|
||||
|
||||
// setupConfigReloadTrap configures a Win32 event to reload the configuration.
|
||||
func (cli *daemonCLI) setupConfigReloadTrap() {
|
||||
ctx := context.TODO()
|
||||
|
||||
func (cli *daemonCLI) setupConfigReloadTrap(ctx context.Context) {
|
||||
go func() {
|
||||
event := `Global\docker-daemon-config-` + strconv.Itoa(os.Getpid())
|
||||
ev, _ := windows.UTF16PtrFromString(event)
|
||||
@@ -91,11 +89,25 @@ func (cli *daemonCLI) setupConfigReloadTrap() {
|
||||
log.G(ctx).WithError(err).Errorf("Failed to create config reload event %s", event)
|
||||
return
|
||||
}
|
||||
defer func() { _ = windows.CloseHandle(h) }()
|
||||
stopDone := make(chan struct{})
|
||||
stop := context.AfterFunc(ctx, func() {
|
||||
// Wake the blocking wait so the goroutine can exit on shutdown.
|
||||
_ = windows.SetEvent(h)
|
||||
close(stopDone)
|
||||
})
|
||||
defer func() {
|
||||
if !stop() {
|
||||
<-stopDone
|
||||
}
|
||||
_ = windows.CloseHandle(h)
|
||||
}()
|
||||
|
||||
log.G(ctx).Debugf("Config reload - waiting signal at %s", event)
|
||||
for {
|
||||
windows.WaitForSingleObject(h, windows.INFINITE)
|
||||
if ctx.Err() != nil {
|
||||
return
|
||||
}
|
||||
cli.reloadConfig()
|
||||
}
|
||||
}()
|
||||
|
||||
Reference in new issue
Block a user