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