Explorar el Código

Use await_shutdown().

Use the new await_shutdown() funtion to wait for the application to stop
rather than calling WaitForSingleObject() directly, so we can update the
service status periodically.
Iain Patterson hace 10 años
padre
commit
99c5c2868f
Se han modificado 3 ficheros con 16 adiciones y 16 borrados
  1. 10 10
      process.cpp
  2. 4 4
      process.h
  3. 2 2
      service.cpp

+ 10 - 10
process.cpp

@@ -139,7 +139,7 @@ int kill_threads(char *service_name, kill_t *k) {
 }
 
 /* Give the process a chance to die gracefully. */
-int kill_process(char *service_name, unsigned long stop_method, HANDLE process_handle, unsigned long pid, unsigned long exitcode) {
+int kill_process(char *service_name, SERVICE_STATUS_HANDLE service_handle, SERVICE_STATUS *service_status, unsigned long stop_method, HANDLE process_handle, unsigned long pid, unsigned long exitcode) {
   /* Shouldn't happen. */
   if (! pid) return 1;
   if (! process_handle) return 1;
@@ -153,7 +153,7 @@ int kill_process(char *service_name, unsigned long stop_method, HANDLE process_h
 
   /* Try to send a Control-C event to the console. */
   if (stop_method & NSSM_STOP_METHOD_CONSOLE) {
-    if (! kill_console(service_name, process_handle, pid)) return 1;
+    if (! kill_console(service_name, service_handle, service_status, process_handle, pid)) return 1;
   }
 
   /*
@@ -164,7 +164,7 @@ int kill_process(char *service_name, unsigned long stop_method, HANDLE process_h
   if (stop_method & NSSM_STOP_METHOD_WINDOW) {
     EnumWindows((WNDENUMPROC) kill_window, (LPARAM) &k);
     if (k.signalled) {
-      if (! WaitForSingleObject(process_handle, kill_window_delay)) return 1;
+      if (! await_shutdown(__FUNCTION__, service_name, service_handle, service_status, process_handle, kill_window_delay)) return 1;
     }
   }
 
@@ -175,7 +175,7 @@ int kill_process(char *service_name, unsigned long stop_method, HANDLE process_h
   */
   if (stop_method & NSSM_STOP_METHOD_THREADS) {
     if (kill_threads(service_name, &k)) {
-      if (! WaitForSingleObject(process_handle, kill_threads_delay)) return 1;
+      if (! await_shutdown(__FUNCTION__, service_name, service_handle, service_status, process_handle, kill_threads_delay)) return 1;
     }
   }
 
@@ -188,7 +188,7 @@ int kill_process(char *service_name, unsigned long stop_method, HANDLE process_h
 }
 
 /* Simulate a Control-C event to our console (shared with the app). */
-int kill_console(char *service_name, HANDLE process_handle, unsigned long pid) {
+int kill_console(char *service_name, SERVICE_STATUS_HANDLE service_handle, SERVICE_STATUS *service_status, HANDLE process_handle, unsigned long pid) {
   unsigned long ret;
 
   /* Check we loaded AttachConsole(). */
@@ -236,12 +236,12 @@ int kill_console(char *service_name, HANDLE process_handle, unsigned long pid) {
   }
 
   /* Wait for process to exit. */
-  if (WaitForSingleObject(process_handle, kill_console_delay)) return 6;
+  if (await_shutdown(__FUNCTION__, service_name, service_handle, service_status, process_handle, kill_console_delay)) ret = 6;
 
   return ret;
 }
 
-void kill_process_tree(char *service_name, unsigned long stop_method, unsigned long pid, unsigned long exitcode, unsigned long ppid, FILETIME *parent_creation_time, FILETIME *parent_exit_time) {
+void kill_process_tree(char *service_name, SERVICE_STATUS_HANDLE service_handle, SERVICE_STATUS *service_status, unsigned long stop_method, unsigned long pid, unsigned long exitcode, unsigned long ppid, FILETIME *parent_creation_time, FILETIME *parent_exit_time) {
   /* Shouldn't happen unless the service failed to start. */
   if (! pid) return;
 
@@ -268,7 +268,7 @@ void kill_process_tree(char *service_name, unsigned long stop_method, unsigned l
   }
 
   /* This is a child of the doomed process so kill it. */
-  if (! check_parent(service_name, &pe, pid, parent_creation_time, parent_exit_time)) kill_process_tree(service_name, stop_method, pe.th32ProcessID, exitcode, ppid, parent_creation_time, parent_exit_time);
+  if (! check_parent(service_name, &pe, pid, parent_creation_time, parent_exit_time)) kill_process_tree(service_name, service_handle, service_status, stop_method, pe.th32ProcessID, exitcode, ppid, parent_creation_time, parent_exit_time);
 
   while (true) {
     /* Try to get the next process. */
@@ -280,7 +280,7 @@ void kill_process_tree(char *service_name, unsigned long stop_method, unsigned l
       return;
     }
 
-    if (! check_parent(service_name, &pe, pid, parent_creation_time, parent_exit_time)) kill_process_tree(service_name, stop_method, pe.th32ProcessID, exitcode, ppid, parent_creation_time, parent_exit_time);
+    if (! check_parent(service_name, &pe, pid, parent_creation_time, parent_exit_time)) kill_process_tree(service_name, service_handle, service_status, stop_method, pe.th32ProcessID, exitcode, ppid, parent_creation_time, parent_exit_time);
   }
 
   CloseHandle(snapshot);
@@ -295,7 +295,7 @@ void kill_process_tree(char *service_name, unsigned long stop_method, unsigned l
   char ppid_string[16];
   _snprintf_s(ppid_string, sizeof(ppid_string), _TRUNCATE, "%lu", ppid);
   log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_KILL_PROCESS_TREE, pid_string, ppid_string, service_name, 0);
-  if (! kill_process(service_name, stop_method, process_handle, pid, exitcode)) {
+  if (! kill_process(service_name, service_handle, service_status, stop_method, process_handle, pid, exitcode)) {
     /* Maybe it already died. */
     unsigned long ret;
     if (! GetExitCodeProcess(process_handle, &ret) || ret == STILL_ACTIVE) {

+ 4 - 4
process.h

@@ -13,9 +13,9 @@ int get_process_creation_time(HANDLE, FILETIME *);
 int get_process_exit_time(HANDLE, FILETIME *);
 int check_parent(char *, PROCESSENTRY32 *, unsigned long, FILETIME *, FILETIME *);
 int CALLBACK kill_window(HWND, LPARAM);
-int kill_threads(char *, kill_t *);
-int kill_console(char *, HANDLE, unsigned long);
-int kill_process(char *, unsigned long, HANDLE, unsigned long, unsigned long);
-void kill_process_tree(char *, unsigned long, unsigned long, unsigned long, unsigned long, FILETIME *, FILETIME *);
+int kill_threads(char *, SERVICE_STATUS_HANDLE, SERVICE_STATUS *, kill_t *);
+int kill_console(char *, SERVICE_STATUS_HANDLE, SERVICE_STATUS *, HANDLE, unsigned long);
+int kill_process(char *, SERVICE_STATUS_HANDLE, SERVICE_STATUS *, unsigned long, HANDLE, unsigned long, unsigned long);
+void kill_process_tree(char *, SERVICE_STATUS_HANDLE, SERVICE_STATUS *, unsigned long, unsigned long, unsigned long, unsigned long, FILETIME *, FILETIME *);
 
 #endif

+ 2 - 2
service.cpp

@@ -459,7 +459,7 @@ int stop_service(unsigned long exitcode, bool graceful, bool default_action) {
   if (pid) {
     /* Shut down service */
     log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_TERMINATEPROCESS, service_name, exe, 0);
-    kill_process(service_name, stop_method, process_handle, pid, 0);
+    kill_process(service_name, service_handle, &service_status, stop_method, process_handle, pid, 0);
   }
   else log_event(EVENTLOG_INFORMATION_TYPE, NSSM_EVENT_PROCESS_ALREADY_STOPPED, service_name, exe, 0);
 
@@ -509,7 +509,7 @@ void CALLBACK end_service(void *arg, unsigned char why) {
 
   /* Clean up. */
   if (exitcode == STILL_ACTIVE) exitcode = 0;
-  kill_process_tree(service_name, stop_method, pid, exitcode, pid, &creation_time, &exit_time);
+  kill_process_tree(service_name, service_handle, &service_status, stop_method, pid, exitcode, pid, &creation_time, &exit_time);
 
   /*
     The why argument is true if our wait timed out or false otherwise.