/src/log4cplus/include/log4cplus/thread/syncprims-pub-impl.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_PUB_IMPL_H |
26 | | #define LOG4CPLUS_THREAD_SYNCPRIMS_PUB_IMPL_H |
27 | | |
28 | | #include <log4cplus/config.hxx> |
29 | | |
30 | | #if defined (LOG4CPLUS_HAVE_PRAGMA_ONCE) |
31 | | #pragma once |
32 | | #endif |
33 | | |
34 | | #include <algorithm> |
35 | | |
36 | | #if (defined (LOG4CPLUS_INLINES_ARE_EXPORTED) \ |
37 | | && defined (LOG4CPLUS_BUILD_DLL)) \ |
38 | | || defined (LOG4CPLUS_ENABLE_SYNCPRIMS_PUB_IMPL) |
39 | | #include <log4cplus/thread/syncprims.h> |
40 | | |
41 | | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
42 | | # include <log4cplus/thread/impl/syncprims-impl.h> |
43 | | #endif |
44 | | |
45 | | #define LOG4CPLUS_THROW_RTE(msg) \ |
46 | 0 | do { log4cplus::thread::impl::syncprims_throw_exception (msg, __FILE__, \ |
47 | 0 | __LINE__); } while (0) |
48 | | |
49 | | namespace log4cplus { namespace thread { |
50 | | |
51 | | namespace impl |
52 | | { |
53 | | |
54 | | LOG4CPLUS_EXPORT void LOG4CPLUS_ATTRIBUTE_NORETURN |
55 | | syncprims_throw_exception(char const * const msg, |
56 | | char const * const file, int line); |
57 | | |
58 | | } |
59 | | |
60 | | // |
61 | | // |
62 | | // |
63 | | |
64 | | LOG4CPLUS_INLINE_EXPORT |
65 | | SimpleMutex::SimpleMutex () |
66 | 0 | LOG4CPLUS_THREADED (: mtx ()) |
67 | 0 | { } |
68 | | |
69 | | |
70 | | LOG4CPLUS_INLINE_EXPORT |
71 | | SimpleMutex::~SimpleMutex () |
72 | 0 | { } |
73 | | |
74 | | |
75 | | LOG4CPLUS_INLINE_EXPORT |
76 | | void |
77 | | SimpleMutex::lock () const |
78 | 0 | { |
79 | 0 | LOG4CPLUS_THREADED (mtx.lock ()); |
80 | 0 | } |
81 | | |
82 | | LOG4CPLUS_INLINE_EXPORT |
83 | | bool |
84 | | SimpleMutex::try_lock () const |
85 | 0 | { |
86 | | #if defined (LOG4CPLUS_SINGLE_THREADED) |
87 | | return true; |
88 | | #else |
89 | 0 | return mtx.try_lock (); |
90 | 0 | #endif |
91 | 0 | } |
92 | | |
93 | | |
94 | | LOG4CPLUS_INLINE_EXPORT |
95 | | void |
96 | | SimpleMutex::unlock () const |
97 | 0 | { |
98 | 0 | LOG4CPLUS_THREADED (mtx.unlock ()); |
99 | 0 | } |
100 | | |
101 | | |
102 | | // |
103 | | // |
104 | | // |
105 | | |
106 | | LOG4CPLUS_INLINE_EXPORT |
107 | | Mutex::Mutex () |
108 | 519k | LOG4CPLUS_THREADED (: mtx ()) |
109 | 519k | { } |
110 | | |
111 | | |
112 | | LOG4CPLUS_INLINE_EXPORT |
113 | | Mutex::~Mutex () |
114 | 517k | { } |
115 | | |
116 | | |
117 | | LOG4CPLUS_INLINE_EXPORT |
118 | | void |
119 | | Mutex::lock () const |
120 | 15.7M | { |
121 | 15.7M | LOG4CPLUS_THREADED (mtx.lock ()); |
122 | 15.7M | } |
123 | | |
124 | | |
125 | | LOG4CPLUS_INLINE_EXPORT |
126 | | void |
127 | | Mutex::unlock () const |
128 | 15.7M | { |
129 | 15.7M | LOG4CPLUS_THREADED (mtx.unlock ()); |
130 | 15.7M | } |
131 | | |
132 | | |
133 | | // |
134 | | // |
135 | | // |
136 | | |
137 | | LOG4CPLUS_INLINE_EXPORT |
138 | | Semaphore::Semaphore (unsigned LOG4CPLUS_THREADED (max_), |
139 | | unsigned LOG4CPLUS_THREADED (initial)) |
140 | | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
141 | 0 | : maximum(max_) |
142 | 0 | , val ((std::min) (maximum, initial)) |
143 | | #endif |
144 | 0 | { } |
145 | | |
146 | | |
147 | | LOG4CPLUS_INLINE_EXPORT |
148 | | Semaphore::~Semaphore () |
149 | 0 | { } |
150 | | |
151 | | |
152 | | LOG4CPLUS_INLINE_EXPORT |
153 | | void |
154 | | Semaphore::unlock () const |
155 | 0 | { |
156 | 0 | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
157 | 0 | std::lock_guard<std::mutex> guard (mtx); |
158 | |
|
159 | 0 | if (val >= maximum) |
160 | 0 | LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val >= max"); |
161 | | |
162 | 0 | ++val; |
163 | 0 | cv.notify_all (); |
164 | 0 | #endif |
165 | 0 | } |
166 | | |
167 | | |
168 | | LOG4CPLUS_INLINE_EXPORT |
169 | | void |
170 | | Semaphore::lock () const |
171 | 0 | { |
172 | 0 | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
173 | 0 | std::unique_lock<std::mutex> guard (mtx); |
174 | |
|
175 | 0 | if (LOG4CPLUS_UNLIKELY(val > maximum)) |
176 | 0 | LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val > max"); |
177 | | |
178 | 0 | while (val == 0) |
179 | 0 | cv.wait (guard); |
180 | |
|
181 | 0 | --val; |
182 | |
|
183 | 0 | if (LOG4CPLUS_UNLIKELY(val >= maximum)) |
184 | 0 | LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val >= max"); |
185 | 0 | #endif |
186 | 0 | } |
187 | | |
188 | | |
189 | | // |
190 | | // |
191 | | // |
192 | | |
193 | | LOG4CPLUS_INLINE_EXPORT |
194 | | ManualResetEvent::ManualResetEvent (bool LOG4CPLUS_THREADED (sig)) |
195 | | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
196 | 0 | : signaled (sig) |
197 | 0 | , sigcount (0) |
198 | | #endif |
199 | 0 | { } |
200 | | |
201 | | |
202 | | LOG4CPLUS_INLINE_EXPORT |
203 | | ManualResetEvent::~ManualResetEvent () |
204 | 0 | { } |
205 | | |
206 | | |
207 | | LOG4CPLUS_INLINE_EXPORT |
208 | | void |
209 | | ManualResetEvent::signal () const |
210 | 0 | { |
211 | 0 | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
212 | 0 | std::unique_lock<std::mutex> guard (mtx); |
213 | |
|
214 | 0 | signaled = true; |
215 | 0 | sigcount += 1; |
216 | 0 | cv.notify_all (); |
217 | 0 | #endif |
218 | 0 | } |
219 | | |
220 | | |
221 | | LOG4CPLUS_INLINE_EXPORT |
222 | | void |
223 | | ManualResetEvent::wait () const |
224 | 0 | { |
225 | 0 | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
226 | 0 | std::unique_lock<std::mutex> guard (mtx); |
227 | |
|
228 | 0 | if (! signaled) |
229 | 0 | { |
230 | 0 | unsigned prev_count = sigcount; |
231 | 0 | do |
232 | 0 | { |
233 | 0 | cv.wait (guard); |
234 | 0 | } |
235 | 0 | while (prev_count == sigcount); |
236 | 0 | } |
237 | 0 | #endif |
238 | 0 | } |
239 | | |
240 | | |
241 | | LOG4CPLUS_INLINE_EXPORT |
242 | | bool |
243 | | ManualResetEvent::timed_wait (unsigned long LOG4CPLUS_THREADED (msec)) const |
244 | 0 | { |
245 | | #if defined (LOG4CPLUS_SINGLE_THREADED) |
246 | | return true; |
247 | | |
248 | | #else |
249 | 0 | std::unique_lock<std::mutex> guard (mtx); |
250 | |
|
251 | 0 | if (! signaled) |
252 | 0 | { |
253 | 0 | unsigned prev_count = sigcount; |
254 | |
|
255 | 0 | std::chrono::steady_clock::time_point const wait_until_time |
256 | 0 | = std::chrono::steady_clock::now () |
257 | 0 | + std::chrono::milliseconds (msec); |
258 | |
|
259 | 0 | do |
260 | 0 | { |
261 | 0 | int ret = static_cast<int>( |
262 | 0 | cv.wait_until (guard, wait_until_time)); |
263 | 0 | switch (ret) |
264 | 0 | { |
265 | 0 | case static_cast<int>(std::cv_status::no_timeout): |
266 | 0 | break; |
267 | | |
268 | 0 | case static_cast<int>(std::cv_status::timeout): |
269 | 0 | return false; |
270 | | |
271 | 0 | default: |
272 | 0 | guard.unlock (); |
273 | 0 | guard.release (); |
274 | 0 | LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait"); |
275 | 0 | } |
276 | 0 | } |
277 | 0 | while (prev_count == sigcount); |
278 | 0 | } |
279 | | |
280 | 0 | return true; |
281 | 0 | #endif |
282 | 0 | } |
283 | | |
284 | | |
285 | | LOG4CPLUS_INLINE_EXPORT |
286 | | void |
287 | | ManualResetEvent::reset () const |
288 | 0 | { |
289 | 0 | #if ! defined (LOG4CPLUS_SINGLE_THREADED) |
290 | 0 | std::lock_guard<std::mutex> guard (mtx); |
291 | |
|
292 | 0 | signaled = false; |
293 | 0 | #endif |
294 | 0 | } |
295 | | |
296 | | |
297 | | // |
298 | | // |
299 | | // |
300 | | |
301 | | LOG4CPLUS_INLINE_EXPORT |
302 | | SharedMutexImplBase::~SharedMutexImplBase () |
303 | 0 | { } |
304 | | |
305 | | |
306 | | // |
307 | | // |
308 | | // |
309 | | |
310 | | LOG4CPLUS_INLINE_EXPORT |
311 | | SharedMutex::SharedMutex () |
312 | 0 | : sm (LOG4CPLUS_THREADED (new impl::SharedMutex)) |
313 | 0 | { } |
314 | | |
315 | | |
316 | | LOG4CPLUS_INLINE_EXPORT |
317 | | SharedMutex::~SharedMutex () |
318 | 0 | { |
319 | 0 | LOG4CPLUS_THREADED (delete static_cast<impl::SharedMutex *>(sm)); |
320 | 0 | } |
321 | | |
322 | | |
323 | | LOG4CPLUS_INLINE_EXPORT |
324 | | void |
325 | | SharedMutex::rdlock () const |
326 | 0 | { |
327 | 0 | LOG4CPLUS_THREADED (static_cast<impl::SharedMutex *>(sm)->rdlock ()); |
328 | 0 | } |
329 | | |
330 | | |
331 | | LOG4CPLUS_INLINE_EXPORT |
332 | | void |
333 | | SharedMutex::wrlock () const |
334 | 0 | { |
335 | 0 | LOG4CPLUS_THREADED (static_cast<impl::SharedMutex *>(sm)->wrlock ()); |
336 | 0 | } |
337 | | |
338 | | |
339 | | LOG4CPLUS_INLINE_EXPORT |
340 | | void |
341 | | SharedMutex::rdunlock () const |
342 | 0 | { |
343 | 0 | LOG4CPLUS_THREADED (static_cast<impl::SharedMutex *>(sm)->rdunlock ()); |
344 | 0 | } |
345 | | |
346 | | |
347 | | LOG4CPLUS_INLINE_EXPORT |
348 | | void |
349 | | SharedMutex::wrunlock () const |
350 | 0 | { |
351 | 0 | LOG4CPLUS_THREADED (static_cast<impl::SharedMutex *>(sm)->wrunlock ()); |
352 | 0 | } |
353 | | |
354 | | |
355 | | } } // namespace log4cplus { namespace thread { |
356 | | |
357 | | #endif // LOG4CPLUS_ENABLE_SYNCPRIMS_PUB_IMPL |
358 | | |
359 | | #endif // LOG4CPLUS_THREAD_SYNCPRIMS_PUB_IMPL_H |