/src/log4cplus/include/log4cplus/thread/syncprims.h
Line | Count | Source |
1 | | // -*- C++ -*- |
2 | | // Copyright (C) 2010-2017, Vaclav Haisman. All rights reserved. |
3 | | // |
4 | | // Redistribution and use in source and binary forms, with or without modifica- |
5 | | // tion, are permitted provided that the following conditions are met: |
6 | | // |
7 | | // 1. Redistributions of source code must retain the above copyright notice, |
8 | | // this list of conditions and the following disclaimer. |
9 | | // |
10 | | // 2. Redistributions in binary form must reproduce the above copyright notice, |
11 | | // this list of conditions and the following disclaimer in the documentation |
12 | | // and/or other materials provided with the distribution. |
13 | | // |
14 | | // THIS SOFTWARE IS PROVIDED ``AS IS'' AND ANY EXPRESSED OR IMPLIED WARRANTIES, |
15 | | // INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND |
16 | | // FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE |
17 | | // APACHE SOFTWARE FOUNDATION OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT, |
18 | | // INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLU- |
19 | | // DING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS |
20 | | // OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON |
21 | | // ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT |
22 | | // (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
23 | | // THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
24 | | |
25 | | #ifndef LOG4CPLUS_THREAD_SYNCPRIMS_H |
26 | | #define LOG4CPLUS_THREAD_SYNCPRIMS_H |
27 | | |
28 | | #include <log4cplus/config.hxx> |
29 | | |
30 | | #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) |
31 | | #pragma once |
32 | | #endif |
33 | | |
34 | | #include <mutex> |
35 | | #include <condition_variable> |
36 | | |
37 | | |
38 | | namespace log4cplus { namespace thread { |
39 | | |
40 | | |
41 | | template <typename SyncPrim> |
42 | | class SyncGuard |
43 | | { |
44 | | public: |
45 | | SyncGuard (); |
46 | | SyncGuard (SyncPrim const &); |
47 | | ~SyncGuard (); |
48 | | SyncGuard (SyncGuard const &) = delete; |
49 | | SyncGuard & operator = (SyncGuard const &) = delete; |
50 | | |
51 | | void lock (); |
52 | | void unlock (); |
53 | | void attach (SyncPrim const &); |
54 | | void attach_and_lock (SyncPrim const &); |
55 | | void detach (); |
56 | | |
57 | | private: |
58 | | SyncPrim const * sp; |
59 | | }; |
60 | | |
61 | | |
62 | | class LOG4CPLUS_EXPORT SimpleMutex |
63 | | { |
64 | | public: |
65 | | SimpleMutex (); |
66 | | ~SimpleMutex (); |
67 | | SimpleMutex (SimpleMutex const &) = delete; |
68 | | SimpleMutex & operator = (SimpleMutex const &) = delete; |
69 | | |
70 | | void lock () const; |
71 | | bool try_lock () const; |
72 | | void unlock () const; |
73 | | |
74 | | private: |
75 | | LOG4CPLUS_THREADED (mutable std::mutex mtx;) |
76 | | }; |
77 | | |
78 | | |
79 | | typedef SyncGuard<SimpleMutex> SimpleMutexGuard; |
80 | | |
81 | | |
82 | | class LOG4CPLUS_EXPORT Mutex |
83 | | { |
84 | | public: |
85 | | Mutex (); |
86 | | ~Mutex (); |
87 | | Mutex (Mutex const &) = delete; |
88 | | Mutex & operator = (Mutex const &) = delete; |
89 | | |
90 | | void lock () const; |
91 | | void unlock () const; |
92 | | |
93 | | private: |
94 | | LOG4CPLUS_THREADED (mutable std::recursive_mutex mtx;) |
95 | | }; |
96 | | |
97 | | |
98 | | typedef SyncGuard<Mutex> MutexGuard; |
99 | | |
100 | | |
101 | | class LOG4CPLUS_EXPORT Semaphore |
102 | | { |
103 | | public: |
104 | | Semaphore (unsigned max, unsigned initial); |
105 | | ~Semaphore (); |
106 | | Semaphore (Semaphore const &) = delete; |
107 | | Semaphore & operator = (Semaphore const &) = delete; |
108 | | |
109 | | void lock () const; |
110 | | void unlock () const; |
111 | | |
112 | | private: |
113 | | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
114 | | mutable std::mutex mtx; |
115 | | mutable std::condition_variable cv; |
116 | | mutable unsigned maximum; |
117 | | mutable unsigned val; |
118 | | #endif |
119 | | }; |
120 | | |
121 | | |
122 | | typedef SyncGuard<Semaphore> SemaphoreGuard; |
123 | | |
124 | | |
125 | | class LOG4CPLUS_EXPORT ManualResetEvent |
126 | | { |
127 | | public: |
128 | | explicit ManualResetEvent (bool = false); |
129 | | ~ManualResetEvent (); |
130 | | ManualResetEvent (ManualResetEvent const &) = delete; |
131 | | ManualResetEvent & operator = (ManualResetEvent const &) = delete; |
132 | | |
133 | | void signal () const; |
134 | | void wait () const; |
135 | | bool timed_wait (unsigned long msec) const; |
136 | | void reset () const; |
137 | | |
138 | | private: |
139 | | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
140 | | mutable std::mutex mtx; |
141 | | mutable std::condition_variable cv; |
142 | | mutable bool signaled; |
143 | | mutable unsigned sigcount; |
144 | | #endif |
145 | | }; |
146 | | |
147 | | |
148 | | class SharedMutexImplBase |
149 | | { |
150 | | protected: |
151 | | ~SharedMutexImplBase (); |
152 | | }; |
153 | | |
154 | | |
155 | | template <typename SyncPrim, void (SyncPrim:: * lock_func) () const, |
156 | | void (SyncPrim:: * unlock_func) () const> |
157 | | class SyncGuardFunc |
158 | | { |
159 | | public: |
160 | | SyncGuardFunc (SyncPrim const &); |
161 | | ~SyncGuardFunc (); |
162 | | |
163 | | void lock (); |
164 | | void unlock (); |
165 | | void attach (SyncPrim const &); |
166 | | void detach (); |
167 | | |
168 | | private: |
169 | | SyncPrim const * sp; |
170 | | |
171 | | SyncGuardFunc (SyncGuardFunc const &); |
172 | | SyncGuardFunc & operator = (SyncGuardFunc const &); |
173 | | }; |
174 | | |
175 | | |
176 | | class LOG4CPLUS_EXPORT SharedMutex |
177 | | { |
178 | | public: |
179 | | SharedMutex (); |
180 | | ~SharedMutex (); |
181 | | |
182 | | void rdlock () const; |
183 | | void rdunlock () const; |
184 | | |
185 | | void wrlock () const; |
186 | | void wrunlock () const; |
187 | | |
188 | | private: |
189 | | SharedMutexImplBase * sm; |
190 | | |
191 | | SharedMutex (SharedMutex const &); |
192 | | SharedMutex & operator = (SharedMutex const &); |
193 | | }; |
194 | | |
195 | | |
196 | | typedef SyncGuardFunc<SharedMutex, &SharedMutex::rdlock, |
197 | | &SharedMutex::rdunlock> SharedMutexReaderGuard; |
198 | | |
199 | | |
200 | | typedef SyncGuardFunc<SharedMutex, &SharedMutex::wrlock, |
201 | | &SharedMutex::wrunlock> SharedMutexWriterGuard; |
202 | | |
203 | | |
204 | | // |
205 | | // |
206 | | // |
207 | | |
208 | | template <typename SyncPrim> |
209 | | inline |
210 | | SyncGuard<SyncPrim>::SyncGuard () |
211 | 664k | : sp (0) |
212 | 664k | { }log4cplus::thread::SyncGuard<log4cplus::helpers::LockFile>::SyncGuard() Line | Count | Source | 211 | 662k | : sp (0) | 212 | 662k | { } |
log4cplus::thread::SyncGuard<log4cplus::thread::Mutex>::SyncGuard() Line | Count | Source | 211 | 1.61k | : sp (0) | 212 | 1.61k | { } |
Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::SimpleMutex>::SyncGuard() |
213 | | |
214 | | |
215 | | template <typename SyncPrim> |
216 | | inline |
217 | | SyncGuard<SyncPrim>::SyncGuard (SyncPrim const & m) |
218 | 11.6M | : sp (&m) |
219 | 11.6M | { |
220 | 11.6M | sp->lock (); |
221 | 11.6M | } log4cplus::thread::SyncGuard<log4cplus::thread::Mutex>::SyncGuard(log4cplus::thread::Mutex const&) Line | Count | Source | 218 | 11.6M | : sp (&m) | 219 | 11.6M | { | 220 | 11.6M | sp->lock (); | 221 | 11.6M | } |
Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::Semaphore>::SyncGuard(log4cplus::thread::Semaphore const&) |
222 | | |
223 | | |
224 | | template <typename SyncPrim> |
225 | | inline |
226 | | SyncGuard<SyncPrim>::~SyncGuard () |
227 | 12.3M | { |
228 | 12.3M | if (sp) |
229 | 11.6M | sp->unlock (); |
230 | 12.3M | } log4cplus::thread::SyncGuard<log4cplus::thread::Mutex>::~SyncGuard() Line | Count | Source | 227 | 11.6M | { | 228 | 11.6M | if (sp) | 229 | 11.6M | sp->unlock (); | 230 | 11.6M | } |
log4cplus::thread::SyncGuard<log4cplus::helpers::LockFile>::~SyncGuard() Line | Count | Source | 227 | 662k | { | 228 | 662k | if (sp) | 229 | 0 | sp->unlock (); | 230 | 662k | } |
Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::Semaphore>::~SyncGuard() Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::SimpleMutex>::~SyncGuard() |
231 | | |
232 | | |
233 | | template <typename SyncPrim> |
234 | | inline |
235 | | void |
236 | | SyncGuard<SyncPrim>::lock () |
237 | 0 | { |
238 | 0 | sp->lock (); |
239 | 0 | } Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::helpers::LockFile>::lock() Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::Mutex>::lock() |
240 | | |
241 | | |
242 | | template <typename SyncPrim> |
243 | | inline |
244 | | void |
245 | | SyncGuard<SyncPrim>::unlock () |
246 | 0 | { |
247 | 0 | sp->unlock (); |
248 | 0 | } |
249 | | |
250 | | |
251 | | template <typename SyncPrim> |
252 | | inline |
253 | | void |
254 | | SyncGuard<SyncPrim>::attach (SyncPrim const & m) |
255 | 0 | { |
256 | 0 | sp = &m; |
257 | 0 | } Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::helpers::LockFile>::attach(log4cplus::helpers::LockFile const&) Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::Mutex>::attach(log4cplus::thread::Mutex const&) Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::SimpleMutex>::attach(log4cplus::thread::SimpleMutex const&) |
258 | | |
259 | | |
260 | | template <typename SyncPrim> |
261 | | inline |
262 | | void |
263 | | SyncGuard<SyncPrim>::attach_and_lock (SyncPrim const & m) |
264 | 0 | { |
265 | 0 | attach (m); |
266 | 0 | try |
267 | 0 | { |
268 | 0 | lock(); |
269 | 0 | } |
270 | 0 | catch (...) |
271 | 0 | { |
272 | 0 | detach (); |
273 | 0 | throw; |
274 | 0 | } |
275 | 0 | } Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::helpers::LockFile>::attach_and_lock(log4cplus::helpers::LockFile const&) Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::Mutex>::attach_and_lock(log4cplus::thread::Mutex const&) |
276 | | |
277 | | |
278 | | template <typename SyncPrim> |
279 | | inline |
280 | | void |
281 | | SyncGuard<SyncPrim>::detach () |
282 | 0 | { |
283 | 0 | sp = 0; |
284 | 0 | } Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::helpers::LockFile>::detach() Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::Mutex>::detach() Unexecuted instantiation: log4cplus::thread::SyncGuard<log4cplus::thread::Semaphore>::detach() |
285 | | |
286 | | |
287 | | // |
288 | | // |
289 | | // |
290 | | |
291 | | template <typename SyncPrim, void (SyncPrim:: * lock_func) () const, |
292 | | void (SyncPrim:: * unlock_func) () const> |
293 | | inline |
294 | | SyncGuardFunc<SyncPrim, lock_func, unlock_func>::SyncGuardFunc (SyncPrim const & m) |
295 | | : sp (&m) |
296 | | { |
297 | | (sp->*lock_func) (); |
298 | | } |
299 | | |
300 | | |
301 | | template <typename SyncPrim, void (SyncPrim:: * lock_func) () const, |
302 | | void (SyncPrim:: * unlock_func) () const> |
303 | | inline |
304 | | SyncGuardFunc<SyncPrim, lock_func, unlock_func>::~SyncGuardFunc () |
305 | | { |
306 | | if (sp) |
307 | | (sp->*unlock_func) (); |
308 | | } |
309 | | |
310 | | |
311 | | template <typename SyncPrim, void (SyncPrim:: * lock_func) () const, |
312 | | void (SyncPrim:: * unlock_func) () const> |
313 | | inline |
314 | | void |
315 | | SyncGuardFunc<SyncPrim, lock_func, unlock_func>::lock () |
316 | | { |
317 | | (sp->*lock_func) (); |
318 | | } |
319 | | |
320 | | |
321 | | template <typename SyncPrim, void (SyncPrim:: * lock_func) () const, |
322 | | void (SyncPrim:: * unlock_func) () const> |
323 | | inline |
324 | | void |
325 | | SyncGuardFunc<SyncPrim, lock_func, unlock_func>::unlock () |
326 | | { |
327 | | (sp->*unlock_func) (); |
328 | | } |
329 | | |
330 | | |
331 | | template <typename SyncPrim, void (SyncPrim:: * lock_func) () const, |
332 | | void (SyncPrim:: * unlock_func) () const> |
333 | | inline |
334 | | void |
335 | | SyncGuardFunc<SyncPrim, lock_func, unlock_func>::attach (SyncPrim const & m) |
336 | | { |
337 | | sp = &m; |
338 | | } |
339 | | |
340 | | |
341 | | template <typename SyncPrim, void (SyncPrim:: * lock_func) () const, |
342 | | void (SyncPrim:: * unlock_func) () const> |
343 | | inline |
344 | | void |
345 | | SyncGuardFunc<SyncPrim, lock_func, unlock_func>::detach () |
346 | | { |
347 | | sp = 0; |
348 | | } |
349 | | |
350 | | |
351 | | } } // namespace log4cplus { namespace thread { |
352 | | |
353 | | |
354 | | #endif // LOG4CPLUS_THREAD_SYNCPRIMS_H |