+ switch (action) {\r
+ /* Try to restart the service or return failure code to service manager */\r
+ case NSSM_EXIT_RESTART:\r
+ log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_RESTART, service_name, code, exit_action_strings[action], exe, 0);\r
+ while (monitor_service()) {\r
+ log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_RESTART_SERVICE_FAILED, exe, service_name, 0);\r
+ Sleep(30000);\r
+ }\r
+ break;\r
+\r
+ /* Do nothing, just like srvany would */\r
+ case NSSM_EXIT_IGNORE:\r
+ log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_IGNORE, service_name, code, exit_action_strings[action], exe, 0);\r
+ Sleep(INFINITE);\r
+ break;\r
+\r
+ /* Tell the service manager we are finished */\r
+ case NSSM_EXIT_REALLY:\r
+ log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_REALLY, service_name, code, exit_action_strings[action], 0);\r
+ stop_service(exitcode, true, default_action);\r
+ break;\r
+\r
+ /* Fake a crash so pre-Vista service managers will run recovery actions. */\r
+ case NSSM_EXIT_UNCLEAN:\r
+ log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_EXIT_UNCLEAN, service_name, code, exit_action_strings[action], 0);\r
+ exit(stop_service(exitcode, false, default_action));\r
+ break;\r
+ }\r
+}\r
+\r
+void throttle_restart() {\r
+ /* This can't be a restart if the service is already running. */\r
+ if (! throttle++) return;\r
+\r
+ int ms = throttle_milliseconds();\r
+\r
+ if (throttle > 7) throttle = 8;\r
+\r
+ char threshold[8], milliseconds[8];\r
+ _snprintf(threshold, sizeof(threshold), "%d", throttle_delay);\r
+ _snprintf(milliseconds, sizeof(milliseconds), "%d", ms);\r
+ log_event(EVENTLOG_WARNING_TYPE, NSSM_EVENT_THROTTLED, service_name, threshold, milliseconds, 0);\r
+\r
+ if (throttle_timer) {\r
+ ZeroMemory(&throttle_duetime, sizeof(throttle_duetime));\r
+ throttle_duetime.QuadPart = 0 - (ms * 10000LL);\r
+ SetWaitableTimer(throttle_timer, &throttle_duetime, 0, 0, 0, 0);\r