if (si->hStdError) CloseHandle(si->hStdError);\r
}\r
\r
+void cleanup_loggers(nssm_service_t *service) {\r
+ unsigned long interval = NSSM_CLEANUP_LOGGERS_DEADLINE;\r
+ HANDLE thread_handle = INVALID_HANDLE_VALUE;\r
+\r
+ close_handle(&service->stdout_thread, &thread_handle);\r
+ /* Close write end of the data pipe so logging thread can finalise read. */\r
+ close_handle(&service->stdout_si);\r
+ /* Await logging thread then close read end. */\r
+ if (thread_handle != INVALID_HANDLE_VALUE) WaitForSingleObject(thread_handle, interval);\r
+ close_handle(&service->stdout_pipe);\r
+\r
+ thread_handle = INVALID_HANDLE_VALUE;\r
+ close_handle(&service->stderr_thread, &thread_handle);\r
+ close_handle(&service->stderr_si);\r
+ if (thread_handle != INVALID_HANDLE_VALUE) WaitForSingleObject(thread_handle, interval);\r
+ close_handle(&service->stderr_pipe);\r
+}\r
+\r
/*\r
Try multiple times to read from a file.\r
Returns: 0 on success.\r
int get_output_handles(nssm_service_t *, STARTUPINFO *);\r
int use_output_handles(nssm_service_t *, STARTUPINFO *);\r
void close_output_handles(STARTUPINFO *);\r
+void cleanup_loggers(nssm_service_t *);\r
unsigned long WINAPI log_and_rotate(void *);\r
\r
#endif\r
/* How many milliseconds to wait for outstanding hooks. */\r
#define NSSM_HOOK_THREAD_DEADLINE 80000\r
\r
+/* How many milliseconds to wait for closing logging thread. */\r
+#define NSSM_CLEANUP_LOGGERS_DEADLINE 1500\r
+\r
#endif\r
service->exit_count++;\r
(void) nssm_hook(&hook_threads, service, NSSM_HOOK_EVENT_EXIT, NSSM_HOOK_ACTION_POST, NULL, NSSM_HOOK_DEADLINE, true);\r
\r
+ /* Exit logging threads. */\r
+ cleanup_loggers(service);\r
+\r
/*\r
The why argument is true if our wait timed out or false otherwise.\r
Our wait is infinite so why will never be true when called by the system.\r