Server core implemented as DLL/shared library
[public/netxms.git] / src / server / core / watchdog.cpp
CommitLineData
f91fa4c2 1/*
a97797f8
VK
2** NetXMS - Network Management System
3** Copyright (C) 2003, 2004 Victor Kirhenshtein
f91fa4c2
VK
4**
5** This program is free software; you can redistribute it and/or modify
6** it under the terms of the GNU General Public License as published by
7** the Free Software Foundation; either version 2 of the License, or
8** (at your option) any later version.
9**
10** This program is distributed in the hope that it will be useful,
11** but WITHOUT ANY WARRANTY; without even the implied warranty of
12** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13** GNU General Public License for more details.
14**
15** You should have received a copy of the GNU General Public License
16** along with this program; if not, write to the Free Software
17** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
18**
19** $module: watchdog.cpp
20**
21**/
22
a551fe4d 23#include "nxcore.h"
f91fa4c2
VK
24
25
26//
27// Constants
28//
29
30#define MAX_THREAD_NAME 64
31#define MAX_THREADS 64
32
33
34//
35// Static data
36//
37
38static struct
39{
40 char szName[MAX_THREAD_NAME];
a97797f8 41 time_t tNotifyInterval;
f91fa4c2
VK
42 time_t tLastCheck;
43 BOOL bNotResponding;
44} m_threadInfo[MAX_THREADS];
45static DWORD m_dwNumThreads = 0;
a97797f8 46static MUTEX m_mutexWatchdogAccess;
f91fa4c2
VK
47
48
49//
50// Add thread to watch list
51//
52
a97797f8 53DWORD WatchdogAddThread(char *szName, time_t tNotifyInterval)
f91fa4c2
VK
54{
55 DWORD dwId;
56
a97797f8 57 MutexLock(m_mutexWatchdogAccess, INFINITE);
f91fa4c2 58 strcpy(m_threadInfo[m_dwNumThreads].szName, szName);
a97797f8 59 m_threadInfo[m_dwNumThreads].tNotifyInterval = tNotifyInterval;
f91fa4c2
VK
60 m_threadInfo[m_dwNumThreads].tLastCheck = time(NULL);
61 m_threadInfo[m_dwNumThreads].bNotResponding = FALSE;
62 dwId = m_dwNumThreads;
63 m_dwNumThreads++;
a97797f8 64 MutexUnlock(m_mutexWatchdogAccess);
f91fa4c2
VK
65 return dwId;
66}
67
68
69//
70// Initialize watchdog
71//
72
73void WatchdogInit(void)
74{
a97797f8 75 m_mutexWatchdogAccess = MutexCreate();
f91fa4c2
VK
76}
77
78
79//
80// Set thread timestamp
81//
82
83void WatchdogNotify(DWORD dwId)
84{
a97797f8
VK
85 if (ShutdownInProgress())
86 return;
87
88 MutexLock(m_mutexWatchdogAccess, INFINITE);
f91fa4c2
VK
89 if (dwId < m_dwNumThreads)
90 {
a97797f8
VK
91 if (m_threadInfo[dwId].bNotResponding)
92 PostEvent(EVENT_THREAD_RUNNING, g_dwMgmtNode, "s", m_threadInfo[dwId].szName);
f91fa4c2 93 m_threadInfo[dwId].tLastCheck = time(NULL);
be0a5a53 94 m_threadInfo[dwId].bNotResponding = FALSE;
f91fa4c2 95 }
a97797f8 96 MutexUnlock(m_mutexWatchdogAccess);
f91fa4c2
VK
97}
98
99
100//
101// Print current thread status
102//
103
104void WatchdogPrintStatus(void)
105{
106 DWORD i;
107
108 if (!IsStandalone())
109 return;
110
a97797f8
VK
111 printf("%-48s Interval Status\n----------------------------------------------------------------------------\n", "Thread");
112 MutexLock(m_mutexWatchdogAccess, INFINITE);
f91fa4c2 113 for(i = 0; i < m_dwNumThreads; i++)
a97797f8 114 printf("%-48s %-8ld %s\n", m_threadInfo[i].szName, m_threadInfo[i].tNotifyInterval,
f91fa4c2 115 m_threadInfo[i].bNotResponding ? "Not responding" : "Running");
a97797f8 116 MutexUnlock(m_mutexWatchdogAccess);
f91fa4c2
VK
117}
118
119
120//
121// Watchdog thread
122//
123
ccdbbb52 124THREAD_RESULT THREAD_CALL WatchdogThread(void *arg)
f91fa4c2
VK
125{
126 DWORD i;
127 time_t currTime;
128
129 while(!ShutdownInProgress())
130 {
a97797f8 131 if (SleepAndCheckForShutdown(20))
f91fa4c2
VK
132 break; // Shutdown has arrived
133
134 // Walk through threads and check if they are alive
a97797f8 135 MutexLock(m_mutexWatchdogAccess, INFINITE);
f91fa4c2
VK
136 currTime = time(NULL);
137 for(i = 0; i < m_dwNumThreads; i++)
a97797f8 138 if ((currTime - m_threadInfo[i].tLastCheck > m_threadInfo[i].tNotifyInterval) &&
f91fa4c2
VK
139 (!m_threadInfo[i].bNotResponding))
140 {
be0a5a53 141 PostEvent(EVENT_THREAD_HANGS, g_dwMgmtNode, "s", m_threadInfo[i].szName);
f91fa4c2
VK
142 WriteLog(MSG_THREAD_HANGS, EVENTLOG_ERROR_TYPE, "s", m_threadInfo[i].szName);
143 m_threadInfo[i].bNotResponding = TRUE;
144 }
a97797f8 145 MutexUnlock(m_mutexWatchdogAccess);
f91fa4c2 146 }
a97797f8
VK
147
148 MutexDestroy(m_mutexWatchdogAccess);
149 m_mutexWatchdogAccess = NULL;
b1dd534d 150 DbgPrintf(AF_DEBUG_MISC, "Watchdog thread terminated");
ccdbbb52 151 return THREAD_OK;
f91fa4c2 152}