]> git.ipfire.org Git - thirdparty/pdns.git/blame - pdns/lock.hh
Replace include guard ifdef/define with pragma once
[thirdparty/pdns.git] / pdns / lock.hh
CommitLineData
12c86877 1/*
12471842
PL
2 * This file is part of PowerDNS or dnsdist.
3 * Copyright -- PowerDNS.COM B.V. and its contributors
4 *
5 * This program is free software; you can redistribute it and/or modify
6 * it under the terms of version 2 of the GNU General Public License as
7 * published by the Free Software Foundation.
8 *
9 * In addition, for the avoidance of any doubt, permission is granted to
10 * link this program with OpenSSL and to (re)distribute the binaries
11 * produced as the result of such linking.
12 *
13 * This program is distributed in the hope that it will be useful,
14 * but WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 * GNU General Public License for more details.
17 *
18 * You should have received a copy of the GNU General Public License
19 * along with this program; if not, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
21 */
e8c59f2d 22#pragma once
12c86877
BH
23#include <pthread.h>
24#include <errno.h>
25#include "misc.hh"
5c409fa2 26#include "pdnsexception.hh"
76698c6e
BH
27
28extern bool g_singleThreaded;
29
12c86877
BH
30class Lock
31{
32 pthread_mutex_t *d_lock;
33public:
2be43892 34 Lock(const Lock& rhs) = delete;
35 Lock& operator=(const Lock& rhs) = delete;
12c86877
BH
36
37 Lock(pthread_mutex_t *lock) : d_lock(lock)
38 {
76698c6e
BH
39 if(g_singleThreaded)
40 return;
d90dad50
RG
41
42 int err;
43 if((err = pthread_mutex_lock(d_lock))) {
44 errno = err;
3f81d239 45 throw PDNSException("error acquiring lock: "+stringerror());
d90dad50 46 }
12c86877
BH
47 }
48 ~Lock()
49 {
76698c6e
BH
50 if(g_singleThreaded)
51 return;
52
12c86877
BH
53 pthread_mutex_unlock(d_lock);
54 }
55};
56
57class WriteLock
58{
59 pthread_rwlock_t *d_lock;
60public:
61
62 WriteLock(pthread_rwlock_t *lock) : d_lock(lock)
63 {
76698c6e
BH
64 if(g_singleThreaded)
65 return;
66
d90dad50
RG
67 int err;
68 if((err = pthread_rwlock_wrlock(d_lock))) {
a2a81d42 69 throw PDNSException("error acquiring rwlock wrlock: "+stringerror(err));
12c86877
BH
70 }
71 }
72 ~WriteLock()
73 {
76698c6e
BH
74 if(g_singleThreaded)
75 return;
2be43892 76 if(d_lock) // might have been moved
77 pthread_rwlock_unlock(d_lock);
78 }
76698c6e 79
2be43892 80 WriteLock(WriteLock&& rhs)
81 {
82 d_lock = rhs.d_lock;
83 rhs.d_lock=0;
12c86877 84 }
2be43892 85 WriteLock(const WriteLock& rhs) = delete;
86 WriteLock& operator=(const WriteLock& rhs) = delete;
87
12c86877
BH
88};
89
90class TryWriteLock
91{
92 pthread_rwlock_t *d_lock;
93 bool d_havelock;
94public:
2be43892 95 TryWriteLock(const TryWriteLock& rhs) = delete;
96 TryWriteLock& operator=(const TryWriteLock& rhs) = delete;
12c86877
BH
97
98 TryWriteLock(pthread_rwlock_t *lock) : d_lock(lock)
99 {
2b808f13
BH
100 if(g_singleThreaded) {
101 d_havelock=true;
76698c6e 102 return;
2b808f13 103 }
76698c6e 104
12c86877 105 d_havelock=false;
d90dad50
RG
106 int err;
107 if((err = pthread_rwlock_trywrlock(d_lock)) && err!=EBUSY) {
a2a81d42 108 throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror(err));
d90dad50
RG
109 }
110 d_havelock=(err==0);
12c86877 111 }
d676748c 112
113 TryWriteLock(TryWriteLock&& rhs)
114 {
115 d_lock = rhs.d_lock;
f10f2f2f
RG
116 rhs.d_lock = nullptr;
117 d_havelock = rhs.d_havelock;
118 rhs.d_havelock = false;
d676748c 119 }
120
121
12c86877
BH
122 ~TryWriteLock()
123 {
76698c6e
BH
124 if(g_singleThreaded)
125 return;
126
d676748c 127 if(d_havelock && d_lock) // we might be moved
12c86877
BH
128 pthread_rwlock_unlock(d_lock);
129 }
130 bool gotIt()
131 {
76698c6e
BH
132 if(g_singleThreaded)
133 return true;
134
12c86877
BH
135 return d_havelock;
136 }
137};
138
139class TryReadLock
140{
141 pthread_rwlock_t *d_lock;
142 bool d_havelock;
143public:
2be43892 144 TryReadLock(const TryReadLock& rhs) = delete;
145 TryReadLock& operator=(const TryReadLock& rhs) = delete;
12c86877
BH
146
147 TryReadLock(pthread_rwlock_t *lock) : d_lock(lock)
148 {
2b808f13
BH
149 if(g_singleThreaded) {
150 d_havelock=true;
76698c6e 151 return;
2b808f13 152 }
76698c6e 153
d90dad50
RG
154 int err;
155 if((err = pthread_rwlock_tryrdlock(d_lock)) && err!=EBUSY) {
a2a81d42 156 throw PDNSException("error acquiring rwlock tryrdlock: "+stringerror(err));
d90dad50
RG
157 }
158 d_havelock=(err==0);
12c86877 159 }
d676748c 160 TryReadLock(TryReadLock&& rhs)
161 {
162 d_lock = rhs.d_lock;
f10f2f2f
RG
163 rhs.d_lock = nullptr;
164 d_havelock = rhs.d_havelock;
165 rhs.d_havelock = false;
d676748c 166 }
167
12c86877
BH
168 ~TryReadLock()
169 {
76698c6e
BH
170 if(g_singleThreaded)
171 return;
172
d676748c 173 if(d_havelock && d_lock)
12c86877
BH
174 pthread_rwlock_unlock(d_lock);
175 }
176 bool gotIt()
177 {
76698c6e
BH
178 if(g_singleThreaded)
179 return true;
180
12c86877
BH
181 return d_havelock;
182 }
183};
184
185
186class ReadLock
187{
188 pthread_rwlock_t *d_lock;
189public:
190
191 ReadLock(pthread_rwlock_t *lock) : d_lock(lock)
192 {
76698c6e
BH
193 if(g_singleThreaded)
194 return;
195
d90dad50
RG
196 int err;
197 if((err = pthread_rwlock_rdlock(d_lock))) {
a2a81d42 198 throw PDNSException("error acquiring rwlock readlock: "+stringerror(err));
d90dad50 199 }
12c86877
BH
200 }
201 ~ReadLock()
202 {
76698c6e
BH
203 if(g_singleThreaded)
204 return;
2be43892 205 if(d_lock) // may have been moved
206 pthread_rwlock_unlock(d_lock);
207 }
76698c6e 208
2be43892 209 ReadLock(ReadLock&& rhs)
210 {
211 d_lock = rhs.d_lock;
212 rhs.d_lock=0;
12c86877 213 }
2be43892 214 ReadLock(const ReadLock& rhs) = delete;
215 ReadLock& operator=(const ReadLock& rhs) = delete;
12c86877 216};