From 816e28277ed0d3fe835fa9df162230eb1a6083b8 Mon Sep 17 00:00:00 2001 From: Daniel Theophanes Date: Sun, 18 Jan 2015 14:30:15 -0800 Subject: [PATCH] service: update windows to return error from Start and Stop methods. --- service_windows.go | 36 +++++++++++++++++++++++++++++++----- 1 file changed, 31 insertions(+), 5 deletions(-) diff --git a/service_windows.go b/service_windows.go index 09ebbed..a61db43 100644 --- a/service_windows.go +++ b/service_windows.go @@ -8,6 +8,7 @@ import ( "fmt" "os" "os/signal" + "sync" "time" "bitbucket.org/kardianos/osext" @@ -21,6 +22,9 @@ const version = "Windows Service" type windowsService struct { i Interface *Config + + errSync sync.Mutex + stopStartErr error } // WindowsLogger allows using windows specific logging methods. @@ -112,13 +116,23 @@ func (ws *windowsService) String() string { return ws.Name } +func (ws *windowsService) setError(err error) { + ws.errSync.Lock() + defer ws.errSync.Unlock() + ws.stopStartErr = err +} +func (ws *windowsService) getError() error { + ws.errSync.Lock() + defer ws.errSync.Unlock() + return ws.stopStartErr +} + func (ws *windowsService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (bool, uint32) { const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown changes <- svc.Status{State: svc.StartPending} if err := ws.i.Start(ws); err != nil { - // TODO: log error. - // ws.Error(err.Error()) + ws.setError(err) return true, 1 } @@ -132,8 +146,7 @@ loop: case svc.Stop, svc.Shutdown: changes <- svc.Status{State: svc.StopPending} if err := ws.i.Stop(ws); err != nil { - // TODO: Log error. - // ws.Error(err.Error()) + ws.setError(err) return true, 2 } break loop @@ -202,8 +215,21 @@ func (ws *windowsService) Uninstall() error { } func (ws *windowsService) Run() error { + ws.setError(nil) if !interactive { - return svc.Run(ws.Name, ws) + // Return error messages from start and stop routines + // that get executed in the Execute method. + // Guarded with a mutex as it may run a different thread + // (callback from windows). + runErr := svc.Run(ws.Name, ws) + startStopErr := ws.getError() + if startStopErr != nil { + return startStopErr + } + if runErr != nil { + return runErr + } + return nil } err := ws.i.Start(ws) if err != nil {