diff options
-rw-r--r-- | include/threads.h | 6 | ||||
-rw-r--r-- | src/libs/zbxwin32/service.c | 13 | ||||
-rw-r--r-- | src/zabbix_agent/zabbix_agentd.c | 39 |
3 files changed, 39 insertions, 19 deletions
diff --git a/include/threads.h b/include/threads.h index 0d380322169..80b05546684 100644 --- a/include/threads.h +++ b/include/threads.h @@ -23,6 +23,8 @@ #include "common.h" #if defined(_WINDOWS) + /* the ZBXEndThread function is implemented in service.c file */ + void CALLBACK ZBXEndThread(ULONG_PTR dwParam); #define ZBX_THREAD_ERROR 0 @@ -39,9 +41,9 @@ _endthreadex((unsigned int)(status)); \ return ((unsigned)(status)) - #define zbx_sleep(sec) Sleep(((DWORD)(sec)) * ((DWORD)1000)) + #define zbx_sleep(sec) SleepEx(((DWORD)(sec)) * ((DWORD)1000), TRUE) - #define zbx_thread_kill(h) TerminateThread(h, SUCCEED); + #define zbx_thread_kill(h) QueueUserAPC(ZBXEndThread, h, 0); #else /* not _WINDOWS */ diff --git a/src/libs/zbxwin32/service.c b/src/libs/zbxwin32/service.c index 691f4a2e147..aabb354cc03 100644 --- a/src/libs/zbxwin32/service.c +++ b/src/libs/zbxwin32/service.c @@ -33,6 +33,9 @@ static SERVICE_STATUS_HANDLE serviceHandle; int application_status = ZBX_APP_RUNNING; +/* free resources allocated by MAIN_ZABBIX_ENTRY() */ +void zbx_free_service_resources(); + static void parent_signal_handler(int sig) { switch (sig) @@ -67,16 +70,13 @@ static VOID WINAPI ServiceCtrlHandler(DWORD ctrlCode) /* notify other threads and allow them to terminate */ ZBX_DO_EXIT(); - zbx_sleep(1); + zbx_free_service_resources(); serviceStatus.dwCurrentState = SERVICE_STOPPED; serviceStatus.dwWaitHint = 0; serviceStatus.dwCheckPoint = 0; serviceStatus.dwWin32ExitCode = 0; - zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Agent stopped. Zabbix %s (revision %s).", - ZABBIX_VERSION, ZABBIX_REVISION); - break; default: break; @@ -400,3 +400,8 @@ void set_parent_signal_handler() signal(SIGINT, parent_signal_handler); signal(SIGTERM, parent_signal_handler); } + +void CALLBACK ZBXEndThread(ULONG_PTR dwParam) +{ + _endthreadex(SUCCEED); +} diff --git a/src/zabbix_agent/zabbix_agentd.c b/src/zabbix_agent/zabbix_agentd.c index e1abb6c5156..18b1205b5bd 100644 --- a/src/zabbix_agent/zabbix_agentd.c +++ b/src/zabbix_agent/zabbix_agentd.c @@ -587,7 +587,7 @@ int MAIN_ZABBIX_ENTRY() else { /* wait for the service worker thread to terminate us */ - zbx_sleep(2); + zbx_sleep(5); THIS_SHOULD_NEVER_HAPPEN; } #else @@ -603,16 +603,20 @@ int MAIN_ZABBIX_ENTRY() /* all exiting child processes should be caught by signal handlers */ THIS_SHOULD_NEVER_HAPPEN; #endif - zbx_on_exit(); return SUCCEED; } -void zbx_on_exit() +/****************************************************************************** + * * + * Function: zbx_free_service_resources * + * * + * Purpose: free service resources allocated by main thread * + * * + ******************************************************************************/ +void zbx_free_service_resources() { - zabbix_log(LOG_LEVEL_DEBUG, "zbx_on_exit() called"); - if (NULL != threads) { int i; @@ -623,24 +627,26 @@ void zbx_on_exit() sigemptyset(&set); sigaddset(&set, SIGCHLD); sigprocmask(SIG_BLOCK, &set, NULL); +#else + /* wait for threads to finish first. although listener threads will never end */ + WaitForMultipleObjectsEx(threads_num, threads, TRUE, 1000, FALSE); #endif for (i = 0; i < threads_num; i++) - { if (threads[i]) - { zbx_thread_kill(threads[i]); - threads[i] = ZBX_THREAD_HANDLE_NULL; - } + + for (i = 0; i < threads_num; i++) + { + if (threads[i]) + zbx_thread_wait(threads[i]); + + threads[i] = ZBX_THREAD_HANDLE_NULL; } zbx_free(threads); } -#ifndef _WINDOWS - zbx_sleep(2); /* wait for all processes to exit */ -#endif - zabbix_log(LOG_LEVEL_INFORMATION, "Zabbix Agent stopped. Zabbix %s (revision %s).", ZABBIX_VERSION, ZABBIX_REVISION); @@ -652,6 +658,13 @@ void zbx_on_exit() #ifdef _WINDOWS free_perf_collector(); #endif +} + +void zbx_on_exit() +{ + zabbix_log(LOG_LEVEL_DEBUG, "zbx_on_exit() called"); + + zbx_free_service_resources(); exit(SUCCEED); } |