From 0182b9ec188609f0f82b9baa9e63cdda1aad0f8c Mon Sep 17 00:00:00 2001
From: Stanislav Chzhen <s.chzhen@adguard.com>
Date: Thu, 31 Aug 2023 17:50:46 +0300
Subject: [PATCH] Pull request 1988: 6158-fix-service-restart

Updates #6158.

Squashed commit of the following:

commit d474a7cb2cdf0a28cf2df320f9095a739241dcc3
Merge: 9c371bde4 53625d891
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 31 17:33:14 2023 +0300

    Merge branch 'master' into 6158-fix-service-restart

commit 9c371bde4b32eee7b5b36766095af3d579e14f2c
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 31 16:53:11 2023 +0300

    aghos: imp code

commit 2722d38ad51ea6b42caf81bbfc41206c95dac358
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 31 16:29:22 2023 +0300

    home: imp code more

commit 50de4c3379cf6e46e5a7cf287381d2b2c3b97127
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 31 16:20:18 2023 +0300

    home: imp code

commit dcba579fbe5cb82bea391bd08caee9df82c2618b
Author: Stanislav Chzhen <s.chzhen@adguard.com>
Date:   Thu Aug 31 14:57:24 2023 +0300

    home: fix service restart for windows
---
 internal/aghos/os.go         |  5 +++++
 internal/aghos/os_unix.go    |  4 ++++
 internal/aghos/os_windows.go |  4 ++++
 internal/home/home.go        |  2 +-
 internal/home/service.go     | 12 +++++++++++-
 5 files changed, 25 insertions(+), 2 deletions(-)

diff --git a/internal/aghos/os.go b/internal/aghos/os.go
index 40c79964..96e5661a 100644
--- a/internal/aghos/os.go
+++ b/internal/aghos/os.go
@@ -182,3 +182,8 @@ func IsReconfigureSignal(sig os.Signal) (ok bool) {
 func IsShutdownSignal(sig os.Signal) (ok bool) {
 	return isShutdownSignal(sig)
 }
+
+// SendShutdownSignal sends the shutdown signal to the channel.
+func SendShutdownSignal(c chan<- os.Signal) {
+	sendShutdownSignal(c)
+}
diff --git a/internal/aghos/os_unix.go b/internal/aghos/os_unix.go
index 6dcc5717..b6ba0a21 100644
--- a/internal/aghos/os_unix.go
+++ b/internal/aghos/os_unix.go
@@ -37,3 +37,7 @@ func isShutdownSignal(sig os.Signal) (ok bool) {
 		return false
 	}
 }
+
+func sendShutdownSignal(_ chan<- os.Signal) {
+	// On Unix we are already notified by the system.
+}
diff --git a/internal/aghos/os_windows.go b/internal/aghos/os_windows.go
index 5568ef4c..b30aa719 100644
--- a/internal/aghos/os_windows.go
+++ b/internal/aghos/os_windows.go
@@ -77,3 +77,7 @@ func isShutdownSignal(sig os.Signal) (ok bool) {
 		return false
 	}
 }
+
+func sendShutdownSignal(c chan<- os.Signal) {
+	c <- os.Interrupt
+}
diff --git a/internal/home/home.go b/internal/home/home.go
index 26def57b..eae9422a 100644
--- a/internal/home/home.go
+++ b/internal/home/home.go
@@ -121,7 +121,7 @@ func Main(clientBuildFS fs.FS) {
 	}()
 
 	if opts.serviceControlAction != "" {
-		handleServiceControlAction(opts, clientBuildFS, done)
+		handleServiceControlAction(opts, clientBuildFS, signals, done)
 
 		return
 	}
diff --git a/internal/home/service.go b/internal/home/service.go
index 74128ec8..1a80ca07 100644
--- a/internal/home/service.go
+++ b/internal/home/service.go
@@ -33,6 +33,7 @@ const (
 // daemon.
 type program struct {
 	clientBuildFS fs.FS
+	signals       chan os.Signal
 	done          chan struct{}
 	opts          options
 }
@@ -55,6 +56,9 @@ func (p *program) Start(_ service.Service) (err error) {
 func (p *program) Stop(_ service.Service) (err error) {
 	log.Info("service: stopping: waiting for cleanup")
 
+	aghos.SendShutdownSignal(p.signals)
+
+	// Wait for other goroutines to complete their job.
 	<-p.done
 
 	return nil
@@ -195,7 +199,12 @@ func restartService() (err error) {
 //   - run:  This is a special command that is not supposed to be used directly
 //     it is specified when we register a service, and it indicates to the app
 //     that it is being run as a service/daemon.
-func handleServiceControlAction(opts options, clientBuildFS fs.FS, done chan struct{}) {
+func handleServiceControlAction(
+	opts options,
+	clientBuildFS fs.FS,
+	signals chan os.Signal,
+	done chan struct{},
+) {
 	// Call chooseSystem explicitly to introduce OpenBSD support for service
 	// package.  It's a noop for other GOOS values.
 	chooseSystem()
@@ -229,6 +238,7 @@ func handleServiceControlAction(opts options, clientBuildFS fs.FS, done chan str
 
 	s, err := service.New(&program{
 		clientBuildFS: clientBuildFS,
+		signals:       signals,
 		done:          done,
 		opts:          runOpts,
 	}, svcConfig)