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