func serviceMain()

in windows/svc/service.go [206:278]


func serviceMain(argc uint32, argv **uint16) uintptr {
	handle, err := windows.RegisterServiceCtrlHandlerEx(windows.StringToUTF16Ptr(theService.name), ctlHandlerCallback, uintptr(unsafe.Pointer(&theService)))
	if sysErr, ok := err.(windows.Errno); ok {
		return uintptr(sysErr)
	} else if err != nil {
		return uintptr(windows.ERROR_UNKNOWN_EXCEPTION)
	}
	theService.h = handle
	defer func() {
		theService.h = 0
	}()
	var args16 []*uint16
	hdr := (*unsafeheader.Slice)(unsafe.Pointer(&args16))
	hdr.Data = unsafe.Pointer(argv)
	hdr.Len = int(argc)
	hdr.Cap = int(argc)

	args := make([]string, len(args16))
	for i, a := range args16 {
		args[i] = windows.UTF16PtrToString(a)
	}

	cmdsToHandler := make(chan ChangeRequest)
	changesFromHandler := make(chan Status)
	exitFromHandler := make(chan exitCode)

	go func() {
		ss, errno := theService.handler.Execute(args, cmdsToHandler, changesFromHandler)
		exitFromHandler <- exitCode{ss, errno}
	}()

	ec := exitCode{isSvcSpecific: true, errno: 0}
	outcr := ChangeRequest{
		CurrentStatus: Status{State: Stopped},
	}
	var outch chan ChangeRequest
	inch := theService.c
loop:
	for {
		select {
		case r := <-inch:
			if r.errno != 0 {
				ec.errno = r.errno
				break loop
			}
			inch = nil
			outch = cmdsToHandler
			outcr.Cmd = r.cmd
			outcr.EventType = r.eventType
			outcr.EventData = r.eventData
			outcr.Context = r.context
		case outch <- outcr:
			inch = theService.c
			outch = nil
		case c := <-changesFromHandler:
			err := theService.updateStatus(&c, &ec)
			if err != nil {
				ec.errno = uint32(windows.ERROR_EXCEPTION_IN_SERVICE)
				if err2, ok := err.(windows.Errno); ok {
					ec.errno = uint32(err2)
				}
				break loop
			}
			outcr.CurrentStatus = c
		case ec = <-exitFromHandler:
			break loop
		}
	}

	theService.updateStatus(&Status{State: Stopped}, &ec)

	return windows.NO_ERROR
}