void fatal_signal_wait(void) { fatal_signal_init(); #ifdef _WIN32 poll_wevent_wait(wevent); #else poll_fd_wait(signal_fds[0], POLLIN); #endif }
/* Return 'true' if the Windows services manager has called the * control_handler() and asked the program to terminate. */ bool should_service_stop(void) { if (service_started) { if (service_status.dwCurrentState != SERVICE_RUNNING) { return true; } else { poll_wevent_wait(wevent); } } return false; }
/* Registers the call-back and configures the actions in case of a failure * with the Windows services manager. */ void service_start(int *argcp, char **argvp[]) { int argc = *argcp; char **argv = *argvp; int i; SERVICE_TABLE_ENTRY service_table[] = { {(LPTSTR)program_name, (LPSERVICE_MAIN_FUNCTION)main}, {NULL, NULL} }; /* If one of the command line option is "--detach", we create * a new process in case of parent, wait for child to start and exit. * In case of the child, we just return. We should not be creating a * service in either case. */ if (detach_process(argc, argv)) { return; } /* 'service_started' is 'false' when service_start() is called the first * time. It is 'true', when it is called the second time by the Windows * services manager. */ if (service_started) { init_service_status(); wevent = CreateEvent(NULL, TRUE, FALSE, NULL); if (!wevent) { char *msg_buf = ovs_lasterror_to_string(); VLOG_FATAL("Failed to create a event (%s).", msg_buf); } poll_wevent_wait(wevent); /* Register the control handler. This function is called by the service * manager to stop the service. */ hstatus = RegisterServiceCtrlHandler(program_name, (LPHANDLER_FUNCTION)control_handler); if (!hstatus) { char *msg_buf = ovs_lasterror_to_string(); VLOG_FATAL("Failed to register the service control handler (%s).", msg_buf); } if (monitor) { set_config_failure_actions(); } /* When the service control manager does the call back, it does not * send the same arguments as sent to the main function during the * service start. So, use the arguments passed over during the first * time. */ *argcp = sargc; *argvp = *sargvp; /* XXX: Windows implementation cannot have a unixctl commands in the * traditional sense of unix domain sockets. If an implementation is * done that involves 'unixctl' vlog commands the following call is * needed to make sure that the unixctl commands for vlog get * registered in a daemon, even before the first log message. */ vlog_init(); return; } assert_single_threaded(); /* A reference to arguments passed to the main function the first time. * We need it after the call-back from service control manager. */ sargc = argc; sargvp = argvp; /* We are only interested in the '--service' and '--service-monitor' * options before the call-back from the service control manager. */ for (i = 0; i < argc; i ++) { if (!strcmp(argv[i], "--service")) { service_create = true; } else if (!strcmp(argv[i], "--service-monitor")) { monitor = true; } } /* If '--service' is not a command line option, run in foreground. */ if (!service_create) { return; } /* If we have been configured to run as a service, then that service * should already have been created either manually or through a start up * script. */ check_service(); service_started = true; /* StartServiceCtrlDispatcher blocks and returns after the service is * stopped. */ if (!StartServiceCtrlDispatcher(service_table)) { char *msg_buf = ovs_lasterror_to_string(); VLOG_FATAL("Failed at StartServiceCtrlDispatcher (%s)", msg_buf); } exit(0); }