agent/app/agent_windows.go
func (h *handler) Execute(args []string, requests <-chan svc.ChangeRequest, responses chan<- svc.Status) (bool, uint32) {
	defer seelog.Flush()
	// channels for communication between goroutines
	ctx, cancel := context.WithCancel(context.Background())
	agentDone := make(chan struct{})
	windowsDone := make(chan struct{})
	wg := sync.WaitGroup{}
	wg.Add(2)

	go func() {
		defer close(windowsDone)
		defer wg.Done()
		h.handleWindowsRequests(ctx, requests, responses)
	}()

	var agentExitCode uint32
	go func() {
		defer close(agentDone)
		defer wg.Done()
		agentExitCode = h.runAgent(ctx)
	}()

	// Wait until one of the goroutines is either told to stop or fails spectacularly.  Under normal conditions we will
	// be waiting here for a long time.
	select {
	case <-windowsDone:
		// Service was told to stop by the Windows API.  This happens either through manual intervention (i.e.,
		// "Stop-Service AmazonECS") or through system shutdown.  Regardless, this is a normal exit event and not an
		// error.
		seelog.Info("Received normal signal from Windows to exit")
	case <-agentDone:
		// This means that the agent stopped on its own.  This is where it's appropriate to light the event log on fire
		// and set off all the alarms.
		seelog.Errorf("Exiting %d", agentExitCode)
	}
	cancel()
	wg.Wait()
	seelog.Infof("Bye Bye! Exiting with %d", agentExitCode)
	return true, agentExitCode
}
func (h *handler) Execute(args []string, requests <-chan svc.ChangeRequest, responses chan<- svc.Status) (bool, uint32) {
	defer seelog.Flush()
	// channels for communication between goroutines
	ctx, cancel := context.WithCancel(context.Background())
	agentDone := make(chan struct{})
	windowsDone := make(chan struct{})
	wg := sync.WaitGroup{}
	wg.Add(2)

	go func() {
		defer close(windowsDone)
		defer wg.Done()
		h.handleWindowsRequests(ctx, requests, responses)
	}()

	var agentExitCode uint32
	go func() {
		defer close(agentDone)
		defer wg.Done()
		agentExitCode = h.runAgent(ctx)
	}()

	// Wait until one of the goroutines is either told to stop or fails spectacularly.  Under normal conditions we will
	// be waiting here for a long time.
	select {
	case <-windowsDone:
		// Service was told to stop by the Windows API.  This happens either through manual intervention (i.e.,
		// "Stop-Service AmazonECS") or through system shutdown.  Regardless, this is a normal exit event and not an
		// error.
		seelog.Info("Received normal signal from Windows to exit")
	case <-agentDone:
		// This means that the agent stopped on its own.  This is where it's appropriate to light the event log on fire
		// and set off all the alarms.
		seelog.Errorf("Exiting %d", agentExitCode)
	}
	cancel()
	wg.Wait()
	seelog.Infof("Bye Bye! Exiting with %d", agentExitCode)
	return true, agentExitCode
}
func ( h * handler ) Execute ( args [ ] string , requests <- chan svc . ChangeRequest , responses chan <- svc . Status ) ( bool , uint32 ) { defer seelog . Flush ( ) // channels for communication between goroutines ctx , cancel := context . WithCancel ( context . Background ( ) ) agentDone := make ( chan struct { } ) windowsDone := make ( chan struct { } ) wg := sync . WaitGroup { } wg . Add ( 2 ) go func ( ) { defer close ( windowsDone ) defer wg . Done ( ) h . handleWindowsRequests ( ctx , requests , responses ) } ( ) var agentExitCode uint32 go func ( ) { defer close ( agentDone ) defer wg . Done ( ) agentExitCode = h . runAgent ( ctx ) } ( ) // Wait until one of the goroutines is either told to stop or fails spectacularly.  Under normal conditions we will // be waiting here for a long time. select { case <- windowsDone : // Service was told to stop by the Windows API.  This happens either through manual intervention (i.e., // "Stop-Service AmazonECS") or through system shutdown.  Regardless, this is a normal exit event and not an // error. seelog . Info ( " " ) case <- agentDone : // This means that the agent stopped on its own.  This is where it's appropriate to light the event log on fire // and set off all the alarms. seelog . Errorf ( " " , agentExitCode ) } cancel ( ) wg . Wait ( ) seelog . Infof ( " " , agentExitCode ) return true , agentExitCode }
// Execute implements https://godoc.org/golang.org/x/sys/windows/svc#Handler
// The basic way that this implementation works is through two channels (representing the requests from Windows and the
// responses we're sending to Windows) and two goroutines (one for message processing with Windows and the other to
// actually run the agent).  Once we've set everything up and started both goroutines, we wait for either one to exit
// (the Windows goroutine will exit based on messages from Windows while the agent goroutine exits if the agent exits)
// and then cancel the other.  Once everything has stopped running, this function returns and the process exits.
Execute implements https : // godoc . org / golang . org / x / sys / windows / svc#Handler The basic way that this implementation works is through two channels ( representing the requests from Windows and the responses we re sending to Windows ) and two goroutines ( one for message processing with Windows and the other to actually run the agent ) . Once we ve set everything up and started both goroutines we wait for either one to exit ( the Windows goroutine will exit based on messages from Windows while the agent goroutine exits if the agent exits ) and then cancel the other . Once everything has stopped running this function returns and the process exits .