- All component locks moved to memory
[public/netxms.git] / src / server / core / locks.cpp
1 /*
2 ** NetXMS - Network Management System
3 ** Copyright (C) 2003, 2004 Victor Kirhenshtein
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: locks.cpp
20 **
21 **/
22
23 #include "nms_core.h"
24
25
26 //
27 // Constants
28 //
29
30 #define MAX_OWNER_INFO 256
31 #define NUMBER_OF_LOCKS 5
32
33
34 //
35 // Lock structure
36 //
37
38 struct LOCK_INFO
39 {
40 DWORD dwLockStatus;
41 TCHAR *pszName;
42 TCHAR szOwnerInfo[MAX_OWNER_INFO];
43 };
44
45
46 //
47 // Static data
48 //
49
50 static MUTEX m_hMutexLockerAccess = NULL;
51 static LOCK_INFO m_locks[NUMBER_OF_LOCKS] =
52 {
53 { UNLOCKED, _T("Event Processing Policy"), _T("") },
54 { UNLOCKED, _T("User Database"), _T("") },
55 { UNLOCKED, _T("Event Configuration Database"), _T("") },
56 { UNLOCKED, _T("Action Configuration Database"), _T("") },
57 { UNLOCKED, _T("SNMP Trap Configuration"), _T("") }
58 };
59
60
61 //
62 // Lock entire database and clear all other locks
63 // Will return FALSE if someone already locked database
64 //
65
66 BOOL InitLocks(DWORD *pdwIpAddr, char *pszInfo)
67 {
68 BOOL bSuccess = FALSE;
69 char szBuffer[256];
70
71 *pdwIpAddr = UNLOCKED;
72 pszInfo[0] = 0;
73
74 // Check current database lock status
75 ConfigReadStr("DBLockStatus", szBuffer, 256, "ERROR");
76 if (!strcmp(szBuffer, "UNLOCKED"))
77 {
78 IpToStr(GetLocalIpAddr(), szBuffer);
79 ConfigWriteStr("DBLockStatus", szBuffer, FALSE);
80 GetSysInfoStr(szBuffer);
81 ConfigWriteStr("DBLockInfo", szBuffer, TRUE);
82 m_hMutexLockerAccess = MutexCreate();
83 bSuccess = TRUE;
84 }
85 else
86 {
87 if (strcmp(szBuffer, "ERROR"))
88 {
89 *pdwIpAddr = ntohl(inet_addr(szBuffer));
90 ConfigReadStr("DBLockInfo", pszInfo, 256, "<error>");
91 }
92 }
93
94 return bSuccess;
95 }
96
97
98 //
99 // Unlock database
100 //
101
102 void UnlockDB(void)
103 {
104 ConfigWriteStr("DBLockStatus", "UNLOCKED", FALSE);
105 ConfigWriteStr("DBLockInfo", "", FALSE);
106 }
107
108
109 //
110 // Lock component
111 // Function will try to lock specified component. On success, will return TRUE.
112 // On failure, will return FALSE and pdwCurrentOwner will be set to the value of lock_status
113 // field, and pszCurrentOwnerInfo will be filled with the value of owner_info field.
114 //
115
116 BOOL LockComponent(DWORD dwId, DWORD dwLockBy, char *pszOwnerInfo,
117 DWORD *pdwCurrentOwner, char *pszCurrentOwnerInfo)
118 {
119 char szBuffer[256];
120 BOOL bSuccess = FALSE;
121 DWORD dwTemp;
122
123 if (pdwCurrentOwner == NULL)
124 pdwCurrentOwner = &dwTemp;
125 if (pszCurrentOwnerInfo == NULL)
126 pszCurrentOwnerInfo = szBuffer;
127
128 if (dwId >= NUMBER_OF_LOCKS)
129 {
130 *pdwCurrentOwner = UNLOCKED;
131 strcpy(pszCurrentOwnerInfo, "Unknown component");
132 return FALSE;
133 }
134
135 DbgPrintf(AF_DEBUG_LOCKS, "*Locks* Attempting to lock component \"%s\" by %d (%s)",
136 m_locks[dwId].pszName, dwLockBy, pszOwnerInfo != NULL ? pszOwnerInfo : "NULL");
137 MutexLock(m_hMutexLockerAccess, INFINITE);
138 if (m_locks[dwId].dwLockStatus == UNLOCKED)
139 {
140 m_locks[dwId].dwLockStatus = dwLockBy;
141 strncpy(m_locks[dwId].szOwnerInfo, pszOwnerInfo, MAX_OWNER_INFO);
142 bSuccess = TRUE;
143 }
144 else
145 {
146 *pdwCurrentOwner = m_locks[dwId].dwLockStatus;
147 strcpy(pszCurrentOwnerInfo, m_locks[dwId].szOwnerInfo);
148 }
149 MutexUnlock(m_hMutexLockerAccess);
150 return bSuccess;
151 }
152
153
154 //
155 // Unlock component
156 //
157
158 void UnlockComponent(DWORD dwId)
159 {
160 MutexLock(m_hMutexLockerAccess, INFINITE);
161 m_locks[dwId].dwLockStatus = UNLOCKED;
162 m_locks[dwId].szOwnerInfo[0] = 0;
163 MutexUnlock(m_hMutexLockerAccess);
164 DbgPrintf(AF_DEBUG_LOCKS, "*Locks* Component \"%s\" unlocked", m_locks[dwId].pszName);
165 }
166
167
168 //
169 // Unlock all locks for specific session
170 //
171
172 void RemoveAllSessionLocks(DWORD dwSessionId)
173 {
174 DWORD i;
175
176 MutexLock(m_hMutexLockerAccess, INFINITE);
177 for(i = 0; i < NUMBER_OF_LOCKS; i++)
178 if (m_locks[i].dwLockStatus == dwSessionId)
179 {
180 m_locks[i].dwLockStatus = UNLOCKED;
181 m_locks[i].szOwnerInfo[0] = 0;
182 }
183 MutexUnlock(m_hMutexLockerAccess);
184 DbgPrintf(AF_DEBUG_LOCKS, "*Locks* All locks for session %d removed", dwSessionId);
185 }