QxOrm 1.4.9
C++ Object Relational Mapping library
Loading...
Searching...
No Matches
fast_mutex.h
Go to the documentation of this file.
1// -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*-
2// vim:tabstop=4:shiftwidth=4:expandtab:
3
4/*
5 * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net>
6 *
7 * This software is provided 'as-is', without any express or implied
8 * warranty. In no event will the authors be held liable for any
9 * damages arising from the use of this software.
10 *
11 * Permission is granted to anyone to use this software for any purpose,
12 * including commercial applications, and to alter it and redistribute
13 * it freely, subject to the following restrictions:
14 *
15 * 1. The origin of this software must not be misrepresented; you must
16 * not claim that you wrote the original software. If you use this
17 * software in a product, an acknowledgement in the product
18 * documentation would be appreciated but is not required.
19 * 2. Altered source versions must be plainly marked as such, and must
20 * not be misrepresented as being the original software.
21 * 3. This notice may not be removed or altered from any source
22 * distribution.
23 *
24 * This file is part of Stones of Nvwa:
25 * http://sourceforge.net/projects/nvwa
26 *
27 */
28
40#ifndef QT_NO_DEBUG
41#ifndef _QX_MODE_RELEASE
42#if _QX_USE_MEM_LEAK_DETECTION
43
44#ifndef _FAST_MUTEX_H
45#define _FAST_MUTEX_H
46
47#ifdef _MSC_VER
48#pragma once
49#endif
50
51# if !defined(_NOTHREADS)
52# if !defined(_WIN32THREADS) && \
53 (defined(_WIN32) && defined(_MT))
54// Automatically use _WIN32THREADS when specifying -MT/-MD in MSVC,
55// or -mthreads in MinGW GCC.
56# define _WIN32THREADS
57# elif !defined(_PTHREADS) && \
58 defined(_REENTRANT)
59// Automatically use _PTHREADS when specifying -pthread in GCC.
60// N.B. I do not detect on _PTHREAD_H since libstdc++-v3 under
61// Linux will silently include <pthread.h> anyway.
62# define _PTHREADS
63# endif
64# endif
65
66# if !defined(_PTHREADS) && !defined(_WIN32THREADS) && !defined(_NOTHREADS)
67# define _NOTHREADS
68# endif
69
70# if defined(_NOTHREADS)
71# if defined(_PTHREADS) || defined(_WIN32THREADS)
72# undef _NOTHREADS
73# error "Cannot define multi-threaded mode with -D_NOTHREADS"
74# if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT)
75# error "Be sure to specify -mthreads with -D_WIN32THREADS"
76# endif
77# endif
78# endif
79
80# ifndef _FAST_MUTEX_CHECK_INITIALIZATION
89# define _FAST_MUTEX_CHECK_INITIALIZATION 1
90# endif
91
92# if defined(_PTHREADS) && defined(_WIN32THREADS)
93// Some C++ libraries have _PTHREADS defined even on Win32 platforms.
94// Thus this hack.
95# undef _PTHREADS
96# endif
97
98#ifndef _QX_MODE_RELEASE
99#ifndef QT_NO_DEBUG
100# include <stdio.h>
101# include <stdlib.h>
103# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
104 if (!(_Expr)) { \
105 fprintf(stderr, "fast_mutex::%s\n", _Msg); \
106 abort(); \
107 }
108#else
110# define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
111 ((void)0)
112#endif // QT_NO_DEBUG
113#endif // _QX_MODE_RELEASE
114
115# ifdef _PTHREADS
116# include <pthread.h>
121# define __VOLATILE volatile
126 namespace qx {
127 namespace memory {
128 class fast_mutex
129 {
130 pthread_mutex_t _M_mtx_impl;
131# if _FAST_MUTEX_CHECK_INITIALIZATION
132 bool _M_initialized;
133# endif
134#ifndef _QX_MODE_RELEASE
135#ifndef QT_NO_DEBUG
136 bool _M_locked;
137#endif // QT_NO_DEBUG
138#endif // _QX_MODE_RELEASE
139 public:
140 fast_mutex()
141#ifndef _QX_MODE_RELEASE
142#ifndef QT_NO_DEBUG
143 : _M_locked(false)
144#endif // QT_NO_DEBUG
145#endif // _QX_MODE_RELEASE
146 {
147 ::pthread_mutex_init(&_M_mtx_impl, NULL);
148# if _FAST_MUTEX_CHECK_INITIALIZATION
149 _M_initialized = true;
150# endif
151 }
153 {
154 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
155# if _FAST_MUTEX_CHECK_INITIALIZATION
156 _M_initialized = false;
157# endif
158 ::pthread_mutex_destroy(&_M_mtx_impl);
159 }
160 void lock()
161 {
162# if _FAST_MUTEX_CHECK_INITIALIZATION
163 if (!_M_initialized)
164 return;
165# endif
166 ::pthread_mutex_lock(&_M_mtx_impl);
167#ifndef _QX_MODE_RELEASE
168#ifndef QT_NO_DEBUG
169 // The following assertion should _always_ be true for a
170 // real `fast' pthread_mutex. However, this assertion can
171 // help sometimes, when people forget to use `-lpthread' and
172 // glibc provides an empty implementation. Having this
173 // assertion is also more consistent.
174 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
175 _M_locked = true;
176#endif // QT_NO_DEBUG
177#endif // _QX_MODE_RELEASE
178 }
179 void unlock()
180 {
181# if _FAST_MUTEX_CHECK_INITIALIZATION
182 if (!_M_initialized)
183 return;
184# endif
185#ifndef _QX_MODE_RELEASE
186#ifndef QT_NO_DEBUG
187 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
188 _M_locked = false;
189#endif // QT_NO_DEBUG
190#endif // _QX_MODE_RELEASE
191 ::pthread_mutex_unlock(&_M_mtx_impl);
192 }
193 private:
194 fast_mutex(const fast_mutex&);
196 };
197 } // namespace memory
198 } // namespace qx
199# endif // _PTHREADS
200
201# ifdef _WIN32THREADS
202# include <windows.h>
207# define __VOLATILE volatile
212 namespace qx {
213 namespace memory {
214 class fast_mutex
215 {
216 CRITICAL_SECTION _M_mtx_impl;
217# if _FAST_MUTEX_CHECK_INITIALIZATION
218 bool _M_initialized;
219# endif
220#ifndef _QX_MODE_RELEASE
221#ifndef QT_NO_DEBUG
222 bool _M_locked;
223#endif // QT_NO_DEBUG
224#endif // _QX_MODE_RELEASE
225 public:
226 fast_mutex()
227#ifndef _QX_MODE_RELEASE
228#ifndef QT_NO_DEBUG
229 : _M_locked(false)
230#endif // QT_NO_DEBUG
231#endif // _QX_MODE_RELEASE
232 {
233 ::InitializeCriticalSection(&_M_mtx_impl);
234# if _FAST_MUTEX_CHECK_INITIALIZATION
235 _M_initialized = true;
236# endif
237 }
239 {
240 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
241# if _FAST_MUTEX_CHECK_INITIALIZATION
242 _M_initialized = false;
243# endif
244 ::DeleteCriticalSection(&_M_mtx_impl);
245 }
246 void lock()
247 {
248# if _FAST_MUTEX_CHECK_INITIALIZATION
249 if (!_M_initialized)
250 return;
251# endif
252 ::EnterCriticalSection(&_M_mtx_impl);
253#ifndef _QX_MODE_RELEASE
254#ifndef QT_NO_DEBUG
255 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
256 _M_locked = true;
257#endif // QT_NO_DEBUG
258#endif // _QX_MODE_RELEASE
259 }
260 void unlock()
261 {
262# if _FAST_MUTEX_CHECK_INITIALIZATION
263 if (!_M_initialized)
264 return;
265# endif
266#ifndef _QX_MODE_RELEASE
267#ifndef QT_NO_DEBUG
268 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
269 _M_locked = false;
270#endif // QT_NO_DEBUG
271#endif // _QX_MODE_RELEASE
272 ::LeaveCriticalSection(&_M_mtx_impl);
273 }
274 private:
275 fast_mutex(const fast_mutex&);
277 };
278 } // namespace memory
279 } // namespace qx
280# endif // _WIN32THREADS
281
282# ifdef _NOTHREADS
287# define __VOLATILE
292 namespace qx {
293 namespace memory {
295 {
296#ifndef _QX_MODE_RELEASE
297#ifndef QT_NO_DEBUG
299#endif // QT_NO_DEBUG
300#endif // _QX_MODE_RELEASE
301 public:
303#ifndef _QX_MODE_RELEASE
304#ifndef QT_NO_DEBUG
305 : _M_locked(false)
306#endif // QT_NO_DEBUG
307#endif // _QX_MODE_RELEASE
308 {
309 }
311 {
312 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
313 }
314 void lock()
315 {
316#ifndef _QX_MODE_RELEASE
317#ifndef QT_NO_DEBUG
318 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
319 _M_locked = true;
320#endif // QT_NO_DEBUG
321#endif // _QX_MODE_RELEASE
322 }
323 void unlock()
324 {
325#ifndef _QX_MODE_RELEASE
326#ifndef QT_NO_DEBUG
327 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
328 _M_locked = false;
329#endif // QT_NO_DEBUG
330#endif // _QX_MODE_RELEASE
331 }
332 private:
335 };
336 } // namespace memory
337 } // namespace qx
338# endif // _NOTHREADS
339
340namespace qx {
341namespace memory {
342
345{
347public:
348 explicit fast_mutex_autolock(fast_mutex& __mtx) : _M_mtx(__mtx)
349 {
350 _M_mtx.lock();
351 }
353 {
354 _M_mtx.unlock();
355 }
356private:
359};
360
361} // namespace memory
362} // namespace qx
363
364#endif // _FAST_MUTEX_H
365#endif // _QX_USE_MEM_LEAK_DETECTION
366#endif // _QX_MODE_RELEASE
367#endif // QT_NO_DEBUG
#define QX_DLL_EXPORT
Definition QxMacro.h:182
fast_mutex_autolock(const fast_mutex_autolock &)
fast_mutex_autolock(fast_mutex &__mtx)
Definition fast_mutex.h:348
fast_mutex_autolock & operator=(const fast_mutex_autolock &)
fast_mutex & operator=(const fast_mutex &)
fast_mutex(const fast_mutex &)
#define _FAST_MUTEX_ASSERT(_Expr, _Msg)
Definition fast_mutex.h:103
Root namespace for all QxOrm library features.