log4cplus  2.1.0
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 
49 namespace log4cplus { namespace thread {
50 
51 namespace 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 
65 Mutex::Mutex ()
66  LOG4CPLUS_THREADED (: mtx ())
67 { }
68 
69 
72 { }
73 
74 
76 void
77 Mutex::lock () const
78 {
79  LOG4CPLUS_THREADED (mtx.lock ());
80 }
81 
82 
84 void
85 Mutex::unlock () const
86 {
87  LOG4CPLUS_THREADED (mtx.unlock ());
88 }
89 
90 
91 //
92 //
93 //
94 
97  unsigned LOG4CPLUS_THREADED (initial))
98 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
99  : maximum(max_)
100  , val ((std::min) (maximum, initial))
101 #endif
102 { }
103 
104 
107 { }
108 
109 
111 void
112 Semaphore::unlock () const
113 {
114 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
115  std::lock_guard<std::mutex> guard (mtx);
116 
117  if (val >= maximum)
118  LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val >= max");
119 
120  ++val;
121  cv.notify_all ();
122 #endif
123 }
124 
125 
127 void
128 Semaphore::lock () const
129 {
130 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
131  std::unique_lock<std::mutex> guard (mtx);
132 
133  if (LOG4CPLUS_UNLIKELY(val > maximum))
134  LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val > max");
135 
136  while (val == 0)
137  cv.wait (guard);
138 
139  --val;
140 
141  if (LOG4CPLUS_UNLIKELY(val >= maximum))
142  LOG4CPLUS_THROW_RTE ("Semaphore::unlock(): val >= max");
143 #endif
144 }
145 
146 
147 //
148 //
149 //
150 
153 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
154  : signaled (sig)
155  , sigcount (0)
156 #endif
157 { }
158 
159 
162 { }
163 
164 
166 void
168 {
169 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
170  std::unique_lock<std::mutex> guard (mtx);
171 
172  signaled = true;
173  sigcount += 1;
174  cv.notify_all ();
175 #endif
176 }
177 
178 
180 void
181 ManualResetEvent::wait () const
182 {
183 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
184  std::unique_lock<std::mutex> guard (mtx);
185 
186  if (! signaled)
187  {
188  unsigned prev_count = sigcount;
189  do
190  {
191  cv.wait (guard);
192  }
193  while (prev_count == sigcount);
194  }
195 #endif
196 }
197 
198 
200 bool
201 ManualResetEvent::timed_wait (unsigned long LOG4CPLUS_THREADED (msec)) const
202 {
203 #if defined (LOG4CPLUS_SINGLE_THREADED)
204  return true;
205 
206 #else
207  std::unique_lock<std::mutex> guard (mtx);
208 
209  if (! signaled)
210  {
211  unsigned prev_count = sigcount;
212 
213  std::chrono::steady_clock::time_point const wait_until_time
215  + std::chrono::milliseconds (msec);
216 
217  do
218  {
219  int ret = static_cast<int>(
220  cv.wait_until (guard, wait_until_time));
221  switch (ret)
222  {
223  case static_cast<int>(std::cv_status::no_timeout):
224  break;
225 
226  case static_cast<int>(std::cv_status::timeout):
227  return false;
228 
229  default:
230  guard.unlock ();
231  guard.release ();
232  LOG4CPLUS_THROW_RTE ("ManualResetEvent::timed_wait");
233  }
234  }
235  while (prev_count == sigcount);
236  }
237 
238  return true;
239 #endif
240 }
241 
242 
244 void
246 {
247 #if ! defined (LOG4CPLUS_SINGLE_THREADED)
248  std::lock_guard<std::mutex> guard (mtx);
249 
250  signaled = false;
251 #endif
252 }
253 
254 
255 //
256 //
257 //
258 
261 { }
262 
263 
264 //
265 //
266 //
267 
270  : sm (LOG4CPLUS_THREADED (new impl::SharedMutex))
271 { }
272 
273 
275 SharedMutex::~SharedMutex ()
276 {
277  LOG4CPLUS_THREADED (delete static_cast<impl::SharedMutex *>(sm));
278 }
279 
280 
282 void
283 SharedMutex::rdlock () const
284 {
285  LOG4CPLUS_THREADED (static_cast<impl::SharedMutex *>(sm)->rdlock ());
286 }
287 
288 
290 void
291 SharedMutex::wrlock () const
292 {
293  LOG4CPLUS_THREADED (static_cast<impl::SharedMutex *>(sm)->wrlock ());
294 }
295 
296 
298 void
299 SharedMutex::rdunlock () const
300 {
301  LOG4CPLUS_THREADED (static_cast<impl::SharedMutex *>(sm)->rdunlock ());
302 }
303 
304 
306 void
307 SharedMutex::wrunlock () const
308 {
309  LOG4CPLUS_THREADED (static_cast<impl::SharedMutex *>(sm)->wrunlock ());
310 }
311 
312 
313 } } // namespace log4cplus { namespace thread {
314 
315 #endif // LOG4CPLUS_ENABLE_SYNCPRIMS_PUB_IMPL
316 
317 #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