From 131aa4c93ccd6e2603e8025dfd4d3693aa9dd561 Mon Sep 17 00:00:00 2001
From: Simon Zolin <s.zolin@adguard.com>
Date: Tue, 2 Jul 2019 12:56:23 +0300
Subject: [PATCH] - service stop: fix race

Service Stop handler sends SIGINT to the main thread,
 which begins the stops the app.
---
 home/config.go  | 1 +
 home/home.go    | 6 +++---
 home/service.go | 8 +++++---
 3 files changed, 9 insertions(+), 6 deletions(-)

diff --git a/home/config.go b/home/config.go
index 8744c842..9a294376 100644
--- a/home/config.go
+++ b/home/config.go
@@ -51,6 +51,7 @@ type configuration struct {
 	// runningAsService flag is set to true when options are passed from the service runner
 	runningAsService bool
 	disableUpdate    bool // If set, don't check for updates
+	appSignalChannel chan os.Signal
 
 	BindHost     string `yaml:"bind_host"`     // BindHost is the IP address of the HTTP server to bind to
 	BindPort     int    `yaml:"bind_port"`     // BindPort is the port the HTTP server
diff --git a/home/home.go b/home/home.go
index c6f0f11d..768bd17a 100644
--- a/home/home.go
+++ b/home/home.go
@@ -99,10 +99,10 @@ func run(args options) {
 		requireAdminRights()
 	}
 
-	signalChannel := make(chan os.Signal)
-	signal.Notify(signalChannel, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
+	config.appSignalChannel = make(chan os.Signal)
+	signal.Notify(config.appSignalChannel, syscall.SIGINT, syscall.SIGTERM, syscall.SIGHUP, syscall.SIGQUIT)
 	go func() {
-		<-signalChannel
+		<-config.appSignalChannel
 		cleanup()
 		cleanupAlways()
 		os.Exit(0)
diff --git a/home/service.go b/home/service.go
index 77b76973..2daf0618 100644
--- a/home/service.go
+++ b/home/service.go
@@ -3,6 +3,7 @@ package home
 import (
 	"os"
 	"runtime"
+	"syscall"
 
 	"github.com/AdguardTeam/golibs/log"
 	"github.com/kardianos/service"
@@ -31,9 +32,10 @@ func (p *program) Start(s service.Service) error {
 // Stop stops the program
 func (p *program) Stop(s service.Service) error {
 	// Stop should not block. Return with a few seconds.
-	cleanup()
-	cleanupAlways()
-	os.Exit(0)
+	if config.appSignalChannel == nil {
+		os.Exit(0)
+	}
+	config.appSignalChannel <- syscall.SIGINT
 	return nil
 }