]> git.ipfire.org Git - thirdparty/pdns.git/blob - pdns/lock.hh
Merge pull request #849 from zeha/f/issue-676
[thirdparty/pdns.git] / pdns / lock.hh
1 /*
2 PowerDNS Versatile Database Driven Nameserver
3 Copyright (C) 2002 PowerDNS.COM BV
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 version 2
7 as published by the Free Software Foundation
8
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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
18 */
19 #ifndef LOCK_HH
20 #define LOCK_HH
21
22 #include <pthread.h>
23 #include <errno.h>
24 #include "misc.hh"
25 #include "pdnsexception.hh"
26
27 extern bool g_singleThreaded;
28
29 class Lock
30 {
31 pthread_mutex_t *d_lock;
32 public:
33
34 Lock(pthread_mutex_t *lock) : d_lock(lock)
35 {
36 if(g_singleThreaded)
37 return;
38 if((errno=pthread_mutex_lock(d_lock)))
39 throw PDNSException("error acquiring lock: "+stringerror());
40 }
41 ~Lock()
42 {
43 if(g_singleThreaded)
44 return;
45
46 pthread_mutex_unlock(d_lock);
47 }
48 };
49
50 class WriteLock
51 {
52 pthread_rwlock_t *d_lock;
53 public:
54
55 WriteLock(pthread_rwlock_t *lock) : d_lock(lock)
56 {
57 if(g_singleThreaded)
58 return;
59
60 if((errno=pthread_rwlock_wrlock(d_lock))) {
61 throw PDNSException("error acquiring rwlock wrlock: "+stringerror());
62 }
63 }
64 ~WriteLock()
65 {
66 if(g_singleThreaded)
67 return;
68
69 pthread_rwlock_unlock(d_lock);
70 }
71 };
72
73 class TryWriteLock
74 {
75 pthread_rwlock_t *d_lock;
76 bool d_havelock;
77 public:
78
79 TryWriteLock(pthread_rwlock_t *lock) : d_lock(lock)
80 {
81 if(g_singleThreaded) {
82 d_havelock=true;
83 return;
84 }
85
86 d_havelock=false;
87 if((errno=pthread_rwlock_trywrlock(d_lock)) && errno!=EBUSY)
88 throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror());
89 d_havelock=(errno==0);
90 }
91 ~TryWriteLock()
92 {
93 if(g_singleThreaded)
94 return;
95
96 if(d_havelock)
97 pthread_rwlock_unlock(d_lock);
98 }
99 bool gotIt()
100 {
101 if(g_singleThreaded)
102 return true;
103
104 return d_havelock;
105 }
106 };
107
108 class TryReadLock
109 {
110 pthread_rwlock_t *d_lock;
111 bool d_havelock;
112 public:
113
114 TryReadLock(pthread_rwlock_t *lock) : d_lock(lock)
115 {
116 if(g_singleThreaded) {
117 d_havelock=true;
118 return;
119 }
120
121 if((errno=pthread_rwlock_tryrdlock(d_lock)) && errno!=EBUSY)
122 throw PDNSException("error acquiring rwlock tryrdlock: "+stringerror());
123 d_havelock=(errno==0);
124 }
125 ~TryReadLock()
126 {
127 if(g_singleThreaded)
128 return;
129
130 if(d_havelock)
131 pthread_rwlock_unlock(d_lock);
132 }
133 bool gotIt()
134 {
135 if(g_singleThreaded)
136 return true;
137
138 return d_havelock;
139 }
140 };
141
142
143 class ReadLock
144 {
145 pthread_rwlock_t *d_lock;
146 public:
147
148 ReadLock(pthread_rwlock_t *lock) : d_lock(lock)
149 {
150 if(g_singleThreaded)
151 return;
152
153 if((errno=pthread_rwlock_rdlock(d_lock)))
154 throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror());
155 }
156 ~ReadLock()
157 {
158 if(g_singleThreaded)
159 return;
160
161 pthread_rwlock_unlock(d_lock);
162 }
163
164 void upgrade()
165 {
166 if(g_singleThreaded)
167 return;
168
169 pthread_rwlock_unlock(d_lock);
170 pthread_rwlock_wrlock(d_lock);
171 }
172 };
173 #endif