in service/service_windows.go [45:100]
func (m *beatService) Execute(args []string, r <-chan svc.ChangeRequest, changes chan<- svc.Status) (ssec bool, errno uint32) {
const cmdsAccepted = svc.AcceptStop | svc.AcceptShutdown
changes <- svc.Status{State: svc.StartPending}
changes <- svc.Status{State: svc.Running, Accepts: cmdsAccepted}
log := logp.NewLogger("service_windows")
combinedChan := make(chan svc.ChangeRequest)
go func() {
for {
select {
case c := <-r:
combinedChan <- c
case <-m.done:
// exits consumption loop on termination and reports stopping
combinedChan <- svc.ChangeRequest{Cmd: svc.Shutdown}
return
}
}
}()
loop:
for c := range combinedChan {
switch c.Cmd {
case svc.Interrogate:
changes <- c.CurrentStatus
// Testing deadlock from https://code.google.com/p/winsvc/issues/detail?id=4
time.Sleep(100 * time.Millisecond)
changes <- c.CurrentStatus
// The svc.Cmd tye does not implement the Stringer interface and its
// underlying type is an integer, therefore it's needed to manually log them.
case svc.Stop:
log.Info("received state change 'svc.Stop' from windows service manager")
break loop
case svc.Shutdown:
log.Info("received state change 'svc.Shutdown' from windows service manager")
break loop
default:
log.Errorf("Unexpected control request: $%d. Ignored.", c)
}
}
trySendState(svc.StopPending, changes)
defer trySendState(svc.Stopped, changes)
log.Info("changed windows service state to svc.StopPending, invoking stopCallback")
m.stopCallback()
// Block until notifyWindowsServiceStopped below is called. This is required
// as the windows/svc package will transition the service to STOPPED state
// once this function returns.
<-m.done
log.Debug("windows service state changed to svc.Stopped")
return ssec, errno
}