]>
Commit | Line | Data |
---|---|---|
12c86877 BH |
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 | |
22dc646a BH |
6 | it under the terms of the GNU General Public License version 2 |
7 | as published by the Free Software Foundation | |
f782fe38 MH |
8 | |
9 | Additionally, the license of this program contains a special | |
10 | exception which allows to distribute the program in binary form when | |
11 | it is linked against OpenSSL. | |
12c86877 BH |
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 | |
06bd9ccf | 20 | Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA |
12c86877 BH |
21 | */ |
22 | #ifndef LOCK_HH | |
23 | #define LOCK_HH | |
24 | ||
25 | #include <pthread.h> | |
26 | #include <errno.h> | |
27 | #include "misc.hh" | |
5c409fa2 | 28 | #include "pdnsexception.hh" |
76698c6e BH |
29 | |
30 | extern bool g_singleThreaded; | |
31 | ||
12c86877 BH |
32 | class Lock |
33 | { | |
34 | pthread_mutex_t *d_lock; | |
35 | public: | |
36 | ||
37 | Lock(pthread_mutex_t *lock) : d_lock(lock) | |
38 | { | |
76698c6e BH |
39 | if(g_singleThreaded) |
40 | return; | |
12c86877 | 41 | if((errno=pthread_mutex_lock(d_lock))) |
3f81d239 | 42 | throw PDNSException("error acquiring lock: "+stringerror()); |
12c86877 BH |
43 | } |
44 | ~Lock() | |
45 | { | |
76698c6e BH |
46 | if(g_singleThreaded) |
47 | return; | |
48 | ||
12c86877 BH |
49 | pthread_mutex_unlock(d_lock); |
50 | } | |
51 | }; | |
52 | ||
53 | class WriteLock | |
54 | { | |
55 | pthread_rwlock_t *d_lock; | |
56 | public: | |
57 | ||
58 | WriteLock(pthread_rwlock_t *lock) : d_lock(lock) | |
59 | { | |
76698c6e BH |
60 | if(g_singleThreaded) |
61 | return; | |
62 | ||
12c86877 | 63 | if((errno=pthread_rwlock_wrlock(d_lock))) { |
3f81d239 | 64 | throw PDNSException("error acquiring rwlock wrlock: "+stringerror()); |
12c86877 BH |
65 | } |
66 | } | |
67 | ~WriteLock() | |
68 | { | |
76698c6e BH |
69 | if(g_singleThreaded) |
70 | return; | |
71 | ||
12c86877 BH |
72 | pthread_rwlock_unlock(d_lock); |
73 | } | |
74 | }; | |
75 | ||
76 | class TryWriteLock | |
77 | { | |
78 | pthread_rwlock_t *d_lock; | |
79 | bool d_havelock; | |
80 | public: | |
81 | ||
82 | TryWriteLock(pthread_rwlock_t *lock) : d_lock(lock) | |
83 | { | |
2b808f13 BH |
84 | if(g_singleThreaded) { |
85 | d_havelock=true; | |
76698c6e | 86 | return; |
2b808f13 | 87 | } |
76698c6e | 88 | |
12c86877 BH |
89 | d_havelock=false; |
90 | if((errno=pthread_rwlock_trywrlock(d_lock)) && errno!=EBUSY) | |
3f81d239 | 91 | throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror()); |
12c86877 BH |
92 | d_havelock=(errno==0); |
93 | } | |
94 | ~TryWriteLock() | |
95 | { | |
76698c6e BH |
96 | if(g_singleThreaded) |
97 | return; | |
98 | ||
12c86877 BH |
99 | if(d_havelock) |
100 | pthread_rwlock_unlock(d_lock); | |
101 | } | |
102 | bool gotIt() | |
103 | { | |
76698c6e BH |
104 | if(g_singleThreaded) |
105 | return true; | |
106 | ||
12c86877 BH |
107 | return d_havelock; |
108 | } | |
109 | }; | |
110 | ||
111 | class TryReadLock | |
112 | { | |
113 | pthread_rwlock_t *d_lock; | |
114 | bool d_havelock; | |
115 | public: | |
116 | ||
117 | TryReadLock(pthread_rwlock_t *lock) : d_lock(lock) | |
118 | { | |
2b808f13 BH |
119 | if(g_singleThreaded) { |
120 | d_havelock=true; | |
76698c6e | 121 | return; |
2b808f13 | 122 | } |
76698c6e | 123 | |
12c86877 | 124 | if((errno=pthread_rwlock_tryrdlock(d_lock)) && errno!=EBUSY) |
3f81d239 | 125 | throw PDNSException("error acquiring rwlock tryrdlock: "+stringerror()); |
12c86877 BH |
126 | d_havelock=(errno==0); |
127 | } | |
128 | ~TryReadLock() | |
129 | { | |
76698c6e BH |
130 | if(g_singleThreaded) |
131 | return; | |
132 | ||
12c86877 BH |
133 | if(d_havelock) |
134 | pthread_rwlock_unlock(d_lock); | |
135 | } | |
136 | bool gotIt() | |
137 | { | |
76698c6e BH |
138 | if(g_singleThreaded) |
139 | return true; | |
140 | ||
12c86877 BH |
141 | return d_havelock; |
142 | } | |
143 | }; | |
144 | ||
145 | ||
146 | class ReadLock | |
147 | { | |
148 | pthread_rwlock_t *d_lock; | |
149 | public: | |
150 | ||
151 | ReadLock(pthread_rwlock_t *lock) : d_lock(lock) | |
152 | { | |
76698c6e BH |
153 | if(g_singleThreaded) |
154 | return; | |
155 | ||
12c86877 | 156 | if((errno=pthread_rwlock_rdlock(d_lock))) |
3f81d239 | 157 | throw PDNSException("error acquiring rwlock tryrwlock: "+stringerror()); |
12c86877 BH |
158 | } |
159 | ~ReadLock() | |
160 | { | |
76698c6e BH |
161 | if(g_singleThreaded) |
162 | return; | |
163 | ||
12c86877 BH |
164 | pthread_rwlock_unlock(d_lock); |
165 | } | |
166 | ||
167 | void upgrade() | |
168 | { | |
76698c6e BH |
169 | if(g_singleThreaded) |
170 | return; | |
171 | ||
12c86877 BH |
172 | pthread_rwlock_unlock(d_lock); |
173 | pthread_rwlock_wrlock(d_lock); | |
174 | } | |
12c86877 | 175 | }; |
12c86877 | 176 | #endif |