Finished rwlock implementation
[public/netxms.git] / src / server / include / rwlock.h
CommitLineData
b8191466
VK
1/*
2** NetXMS - Network Management System
3** Server Library
4** Copyright (C) 2003, 2004 Victor Kirhenshtein
5**
6** This program is free software; you can redistribute it and/or modify
7** it under the terms of the GNU General Public License as published by
8** the Free Software Foundation; either version 2 of the License, or
9** (at your option) any later version.
10**
11** This program is distributed in the hope that it will be useful,
12** but WITHOUT ANY WARRANTY; without even the implied warranty of
13** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14** GNU General Public License for more details.
15**
16** You should have received a copy of the GNU General Public License
17** along with this program; if not, write to the Free Software
18** Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
19**
20** $module: rwlock.h
21**
22**/
23
24#ifndef _rwlock_h_
25#define _rwlock_h_
26
27#include <nms_threads.h>
28
29#if HAVE_PTHREAD_RWLOCK
30
31typedef pthread_rwlock_t * RWLOCK;
32
33inline RWLOCK RWLockCreate(void)
34{
35 RWLOCK hLock;
36
37 hLock = (RWLOCK)malloc(sizeof(pthread_rwlock_t));
38 if (pthread_rwlock_init(hLock, NULL) != 0)
39 {
40 free(hLock);
41 hLock = NULL;
42 }
43 return hLock;
44}
45
46inline void RWLockDestroy(RWLOCK hLock)
47{
48 if (hLock != NULL)
49 {
50 pthread_rwlock_destroy(hLock);
51 free(hLock);
52 }
53}
54
55inline BOOL RWLockReadLock(RWLOCK hLock, DWORD dwTimeOut)
56{
57 int i;
58 BOOL ret = FALSE;
59
60 if (hLock != NULL)
61 {
62 if (dwTimeOut == INFINITE)
63 {
64 if (pthread_rwlock_rdlock(hLock) == 0)
65 {
66 ret = TRUE;
67 }
68 }
69 else
70 {
71 for (i = (dwTimeOut / 50) + 1; i > 0; i--)
72 {
73 if (pthread_rwlock_tryrdlock(hLock) == 0)
74 {
75 ret = TRUE;
76 break;
77 }
78 ThreadSleepMs(50);
79 }
80 }
81 }
82 return ret;
83}
84
85inline BOOL RWLockWriteLock(RWLOCK hLock, DWORD dwTimeOut)
86{
87 int i;
88 BOOL ret = FALSE;
89
90 if (hLock != NULL)
91 {
92 if (dwTimeOut == INFINITE)
93 {
94 if (pthread_rwlock_wrlock(hLock) == 0)
95 {
96 ret = TRUE;
97 }
98 }
99 else
100 {
101 for (i = (dwTimeOut / 50) + 1; i > 0; i--)
102 {
103 if (pthread_rwlock_trywrlock(hLock) == 0)
104 {
105 ret = TRUE;
106 break;
107 }
108 ThreadSleepMs(50);
109 }
110 }
111 }
112 return ret;
113}
114
115inline void RWLockUnlock(RWLOCK hLock)
116{
117 if (hLock != NULL)
118 pthread_rwlock_unlock(hLock);
119}
120
121#else
122
123struct __rwlock_data
124{
125 MUTEX m_mutex;
126 CONDITION m_condRead;
127 CONDITION m_condWrite;
128 DWORD m_dwWaitReaders;
129 DWORD m_dwWaitWriters;
130 int m_iRefCount; // -1 for write lock, otherwise number of read locks
131};
132
133typedef struct __rwlock_data * RWLOCK;
134
135RWLOCK LIBNXSRV_EXPORTABLE RWLockCreate(void);
136void LIBNXSRV_EXPORTABLE RWLockDestroy(RWLOCK hLock);
137BOOL LIBNXSRV_EXPORTABLE RWLockReadLock(RWLOCK hLock, DWORD dwTimeOut);
138BOOL LIBNXSRV_EXPORTABLE RWLockWriteLock(RWLOCK hLock, DWORD dwTimeOut);
139void LIBNXSRV_EXPORTABLE RWLockUnlock(RWLOCK hLock);
140
141#endif
142
143#endif