- Changes in logging and debug output
[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 // Static data
28 //
29
30 static MUTEX m_hMutexLockerAccess;
31
32
33 //
34 // Lock entire database and clear all other locks
35 // Will return FALSE if someone already locked database
36 //
37
38 BOOL InitLocks(DWORD *pdwIpAddr, char *pszInfo)
39 {
40 DB_RESULT hResult;
41 BOOL bSuccess = FALSE;
42 DWORD dwStatus;
43
44 *pdwIpAddr = UNLOCKED;
45 pszInfo[0] = 0;
46
47 hResult = DBSelect(g_hCoreDB, "SELECT lock_status,owner_info FROM locks WHERE component_id=0");
48 if (hResult != NULL)
49 {
50 if (DBGetNumRows(hResult) > 0)
51 {
52 dwStatus = DBGetFieldULong(hResult, 0, 0);
53 if (dwStatus != UNLOCKED)
54 {
55 // Database is locked by someone else, fetch owner info
56 *pdwIpAddr = dwStatus;
57 strcpy(pszInfo, DBGetField(hResult, 0, 1));
58 }
59 else
60 {
61 char szQuery[1024], szSysInfo[512];
62
63 // Lock database
64 GetSysInfoStr(szSysInfo);
65 sprintf(szQuery, "UPDATE locks SET lock_status=%ld,owner_info='%s' WHERE component_id=0",
66 GetLocalIpAddr(), szSysInfo);
67 DBQuery(g_hCoreDB, szQuery);
68 bSuccess = TRUE;
69 }
70 }
71 DBFreeResult(hResult);
72 }
73
74 // Clear all locks and create mutex if we was successfully locked the database
75 if (bSuccess)
76 {
77 DBQuery(g_hCoreDB, "UPDATE locks SET lock_status=-1,owner_info='' WHERE COMPONENT_id<>0");
78 m_hMutexLockerAccess = MutexCreate();
79 }
80
81 return bSuccess;
82 }
83
84
85 //
86 // Lock component
87 // Function will try to lock specified component. On success, will return TRUE.
88 // On failure, will return FALSE and pdwCurrentOwner will be set to the value of lock_status
89 // field, and pszCurrentOwnerInfo will be filled with the value of owner_info field.
90 //
91
92 BOOL LockComponent(DWORD dwId, DWORD dwLockBy, char *pszOwnerInfo,
93 DWORD *pdwCurrentOwner, char *pszCurrentOwnerInfo)
94 {
95 char szQuery[256], szBuffer[256];
96 DB_RESULT hResult;
97 BOOL bSuccess = FALSE;
98 DWORD dwTemp;
99
100 if (pdwCurrentOwner == NULL)
101 pdwCurrentOwner = &dwTemp;
102 if (pszCurrentOwnerInfo == NULL)
103 pszCurrentOwnerInfo = szBuffer;
104
105 DbgPrintf(AF_DEBUG_LOCKS, "*Locks* Attempting to lock component %d by %d (%s)",
106 dwId, dwLockBy, pszOwnerInfo != NULL ? pszOwnerInfo : "NULL");
107 MutexLock(m_hMutexLockerAccess, INFINITE);
108 sprintf(szQuery, "SELECT lock_status,owner_info FROM locks WHERE component_id=%ld", dwId);
109 hResult = DBSelect(g_hCoreDB, szQuery);
110 if (hResult != NULL)
111 {
112 if (DBGetNumRows(hResult) > 0)
113 {
114 *pdwCurrentOwner = DBGetFieldULong(hResult, 0, 0);
115 strcpy(pszCurrentOwnerInfo, DBGetField(hResult, 0, 1));
116 DBFreeResult(hResult);
117 if (*pdwCurrentOwner == UNLOCKED)
118 {
119 sprintf(szQuery, "UPDATE locks SET lock_status=%d,owner_info='%s' WHERE component_id=%ld",
120 dwLockBy, pszOwnerInfo != NULL ? pszOwnerInfo : "", dwId);
121 DBQuery(g_hCoreDB, szQuery);
122 bSuccess = TRUE;
123 }
124 }
125 else
126 {
127 *pdwCurrentOwner = UNLOCKED;
128 strcpy(pszCurrentOwnerInfo, "Unknown component");
129 }
130 }
131 else
132 {
133 *pdwCurrentOwner = UNLOCKED;
134 strcpy(pszCurrentOwnerInfo, "SQL query failed");
135 }
136 MutexUnlock(m_hMutexLockerAccess);
137 return bSuccess;
138 }
139
140
141 //
142 // Unlock component
143 //
144
145 void UnlockComponent(DWORD dwId)
146 {
147 char szQuery[256];
148
149 MutexLock(m_hMutexLockerAccess, INFINITE);
150 sprintf(szQuery, "UPDATE locks SET lock_status=-1,owner_info='' WHERE component_id=%ld", dwId);
151 DBQuery(g_hCoreDB, szQuery);
152 MutexUnlock(m_hMutexLockerAccess);
153 DbgPrintf(AF_DEBUG_LOCKS, "*Locks* Component %d unlocked", dwId);
154 }
155
156
157 //
158 // Unlock all locks for specific session
159 //
160
161 void RemoveAllSessionLocks(DWORD dwSessionId)
162 {
163 char szQuery[256];
164
165 MutexLock(m_hMutexLockerAccess, INFINITE);
166 sprintf(szQuery, "UPDATE locks SET lock_status=-1,owner_info='' "
167 "WHERE (component_id <> 0) AND (lock_status = %d)", dwSessionId);
168 DBQuery(g_hCoreDB, szQuery);
169 MutexUnlock(m_hMutexLockerAccess);
170 DbgPrintf(AF_DEBUG_LOCKS, "*Locks* All locks for session %d removed", dwSessionId);
171 }