Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/zabbix/zabbix.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/threads.h6
-rw-r--r--src/libs/zbxwin32/service.c13
-rw-r--r--src/zabbix_agent/zabbix_agentd.c39
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);
}