QxOrm
1.5.0
C++ Object Relational Mapping library
|
00001 // -*- Mode: C++; tab-width: 4; c-basic-offset: 4; indent-tabs-mode: nil -*- 00002 // vim:tabstop=4:shiftwidth=4:expandtab: 00003 00004 /* 00005 * Copyright (C) 2004-2008 Wu Yongwei <adah at users dot sourceforge dot net> 00006 * 00007 * This software is provided 'as-is', without any express or implied 00008 * warranty. In no event will the authors be held liable for any 00009 * damages arising from the use of this software. 00010 * 00011 * Permission is granted to anyone to use this software for any purpose, 00012 * including commercial applications, and to alter it and redistribute 00013 * it freely, subject to the following restrictions: 00014 * 00015 * 1. The origin of this software must not be misrepresented; you must 00016 * not claim that you wrote the original software. If you use this 00017 * software in a product, an acknowledgement in the product 00018 * documentation would be appreciated but is not required. 00019 * 2. Altered source versions must be plainly marked as such, and must 00020 * not be misrepresented as being the original software. 00021 * 3. This notice may not be removed or altered from any source 00022 * distribution. 00023 * 00024 * This file is part of Stones of Nvwa: 00025 * http://sourceforge.net/projects/nvwa 00026 * 00027 */ 00028 00040 #ifndef QT_NO_DEBUG 00041 #ifndef _QX_MODE_RELEASE 00042 #if _QX_USE_MEM_LEAK_DETECTION 00043 00044 #ifndef _FAST_MUTEX_H 00045 #define _FAST_MUTEX_H 00046 00047 #ifdef _MSC_VER 00048 #pragma once 00049 #endif 00050 00051 # if !defined(_NOTHREADS) 00052 # if !defined(_WIN32THREADS) && \ 00053 (defined(_WIN32) && defined(_MT)) 00054 // Automatically use _WIN32THREADS when specifying -MT/-MD in MSVC, 00055 // or -mthreads in MinGW GCC. 00056 # define _WIN32THREADS 00057 # elif !defined(_PTHREADS) && \ 00058 defined(_REENTRANT) 00059 // Automatically use _PTHREADS when specifying -pthread in GCC. 00060 // N.B. I do not detect on _PTHREAD_H since libstdc++-v3 under 00061 // Linux will silently include <pthread.h> anyway. 00062 # define _PTHREADS 00063 # endif 00064 # endif 00065 00066 # if !defined(_PTHREADS) && !defined(_WIN32THREADS) && !defined(_NOTHREADS) 00067 # define _NOTHREADS 00068 # endif 00069 00070 # if defined(_NOTHREADS) 00071 # if defined(_PTHREADS) || defined(_WIN32THREADS) 00072 # undef _NOTHREADS 00073 # error "Cannot define multi-threaded mode with -D_NOTHREADS" 00074 # if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT) 00075 # error "Be sure to specify -mthreads with -D_WIN32THREADS" 00076 # endif 00077 # endif 00078 # endif 00079 00080 # ifndef _FAST_MUTEX_CHECK_INITIALIZATION 00081 00089 # define _FAST_MUTEX_CHECK_INITIALIZATION 1 00090 # endif 00091 00092 # if defined(_PTHREADS) && defined(_WIN32THREADS) 00093 // Some C++ libraries have _PTHREADS defined even on Win32 platforms. 00094 // Thus this hack. 00095 # undef _PTHREADS 00096 # endif 00097 00098 #ifndef _QX_MODE_RELEASE 00099 #ifndef QT_NO_DEBUG 00100 # include <stdio.h> 00101 # include <stdlib.h> 00103 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \ 00104 if (!(_Expr)) { \ 00105 fprintf(stderr, "fast_mutex::%s\n", _Msg); \ 00106 abort(); \ 00107 } 00108 #else 00109 00110 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \ 00111 ((void)0) 00112 #endif // QT_NO_DEBUG 00113 #endif // _QX_MODE_RELEASE 00114 00115 # ifdef _PTHREADS 00116 # include <pthread.h> 00121 # define __VOLATILE volatile 00122 00126 namespace qx { 00127 namespace memory { 00128 class fast_mutex 00129 { 00130 pthread_mutex_t _M_mtx_impl; 00131 # if _FAST_MUTEX_CHECK_INITIALIZATION 00132 bool _M_initialized; 00133 # endif 00134 #ifndef _QX_MODE_RELEASE 00135 #ifndef QT_NO_DEBUG 00136 bool _M_locked; 00137 #endif // QT_NO_DEBUG 00138 #endif // _QX_MODE_RELEASE 00139 public: 00140 fast_mutex() 00141 #ifndef _QX_MODE_RELEASE 00142 #ifndef QT_NO_DEBUG 00143 : _M_locked(false) 00144 #endif // QT_NO_DEBUG 00145 #endif // _QX_MODE_RELEASE 00146 { 00147 ::pthread_mutex_init(&_M_mtx_impl, NULL); 00148 # if _FAST_MUTEX_CHECK_INITIALIZATION 00149 _M_initialized = true; 00150 # endif 00151 } 00152 ~fast_mutex() 00153 { 00154 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); 00155 # if _FAST_MUTEX_CHECK_INITIALIZATION 00156 _M_initialized = false; 00157 # endif 00158 ::pthread_mutex_destroy(&_M_mtx_impl); 00159 } 00160 void lock() 00161 { 00162 # if _FAST_MUTEX_CHECK_INITIALIZATION 00163 if (!_M_initialized) 00164 return; 00165 # endif 00166 ::pthread_mutex_lock(&_M_mtx_impl); 00167 #ifndef _QX_MODE_RELEASE 00168 #ifndef QT_NO_DEBUG 00169 // The following assertion should _always_ be true for a 00170 // real `fast' pthread_mutex. However, this assertion can 00171 // help sometimes, when people forget to use `-lpthread' and 00172 // glibc provides an empty implementation. Having this 00173 // assertion is also more consistent. 00174 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); 00175 _M_locked = true; 00176 #endif // QT_NO_DEBUG 00177 #endif // _QX_MODE_RELEASE 00178 } 00179 void unlock() 00180 { 00181 # if _FAST_MUTEX_CHECK_INITIALIZATION 00182 if (!_M_initialized) 00183 return; 00184 # endif 00185 #ifndef _QX_MODE_RELEASE 00186 #ifndef QT_NO_DEBUG 00187 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); 00188 _M_locked = false; 00189 #endif // QT_NO_DEBUG 00190 #endif // _QX_MODE_RELEASE 00191 ::pthread_mutex_unlock(&_M_mtx_impl); 00192 } 00193 private: 00194 fast_mutex(const fast_mutex&); 00195 fast_mutex& operator=(const fast_mutex&); 00196 }; 00197 } // namespace memory 00198 } // namespace qx 00199 # endif // _PTHREADS 00200 00201 # ifdef _WIN32THREADS 00202 # include <windows.h> 00207 # define __VOLATILE volatile 00208 00212 namespace qx { 00213 namespace memory { 00214 class fast_mutex 00215 { 00216 CRITICAL_SECTION _M_mtx_impl; 00217 # if _FAST_MUTEX_CHECK_INITIALIZATION 00218 bool _M_initialized; 00219 # endif 00220 #ifndef _QX_MODE_RELEASE 00221 #ifndef QT_NO_DEBUG 00222 bool _M_locked; 00223 #endif // QT_NO_DEBUG 00224 #endif // _QX_MODE_RELEASE 00225 public: 00226 fast_mutex() 00227 #ifndef _QX_MODE_RELEASE 00228 #ifndef QT_NO_DEBUG 00229 : _M_locked(false) 00230 #endif // QT_NO_DEBUG 00231 #endif // _QX_MODE_RELEASE 00232 { 00233 ::InitializeCriticalSection(&_M_mtx_impl); 00234 # if _FAST_MUTEX_CHECK_INITIALIZATION 00235 _M_initialized = true; 00236 # endif 00237 } 00238 ~fast_mutex() 00239 { 00240 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); 00241 # if _FAST_MUTEX_CHECK_INITIALIZATION 00242 _M_initialized = false; 00243 # endif 00244 ::DeleteCriticalSection(&_M_mtx_impl); 00245 } 00246 void lock() 00247 { 00248 # if _FAST_MUTEX_CHECK_INITIALIZATION 00249 if (!_M_initialized) 00250 return; 00251 # endif 00252 ::EnterCriticalSection(&_M_mtx_impl); 00253 #ifndef _QX_MODE_RELEASE 00254 #ifndef QT_NO_DEBUG 00255 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); 00256 _M_locked = true; 00257 #endif // QT_NO_DEBUG 00258 #endif // _QX_MODE_RELEASE 00259 } 00260 void unlock() 00261 { 00262 # if _FAST_MUTEX_CHECK_INITIALIZATION 00263 if (!_M_initialized) 00264 return; 00265 # endif 00266 #ifndef _QX_MODE_RELEASE 00267 #ifndef QT_NO_DEBUG 00268 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); 00269 _M_locked = false; 00270 #endif // QT_NO_DEBUG 00271 #endif // _QX_MODE_RELEASE 00272 ::LeaveCriticalSection(&_M_mtx_impl); 00273 } 00274 private: 00275 fast_mutex(const fast_mutex&); 00276 fast_mutex& operator=(const fast_mutex&); 00277 }; 00278 } // namespace memory 00279 } // namespace qx 00280 # endif // _WIN32THREADS 00281 00282 # ifdef _NOTHREADS 00283 00287 # define __VOLATILE 00288 00292 namespace qx { 00293 namespace memory { 00294 class fast_mutex 00295 { 00296 #ifndef _QX_MODE_RELEASE 00297 #ifndef QT_NO_DEBUG 00298 bool _M_locked; 00299 #endif // QT_NO_DEBUG 00300 #endif // _QX_MODE_RELEASE 00301 public: 00302 fast_mutex() 00303 #ifndef _QX_MODE_RELEASE 00304 #ifndef QT_NO_DEBUG 00305 : _M_locked(false) 00306 #endif // QT_NO_DEBUG 00307 #endif // _QX_MODE_RELEASE 00308 { 00309 } 00310 ~fast_mutex() 00311 { 00312 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked"); 00313 } 00314 void lock() 00315 { 00316 #ifndef _QX_MODE_RELEASE 00317 #ifndef QT_NO_DEBUG 00318 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked"); 00319 _M_locked = true; 00320 #endif // QT_NO_DEBUG 00321 #endif // _QX_MODE_RELEASE 00322 } 00323 void unlock() 00324 { 00325 #ifndef _QX_MODE_RELEASE 00326 #ifndef QT_NO_DEBUG 00327 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked"); 00328 _M_locked = false; 00329 #endif // QT_NO_DEBUG 00330 #endif // _QX_MODE_RELEASE 00331 } 00332 private: 00333 fast_mutex(const fast_mutex&); 00334 fast_mutex& operator=(const fast_mutex&); 00335 }; 00336 } // namespace memory 00337 } // namespace qx 00338 # endif // _NOTHREADS 00339 00340 namespace qx { 00341 namespace memory { 00342 00344 class QX_DLL_EXPORT fast_mutex_autolock 00345 { 00346 fast_mutex& _M_mtx; 00347 public: 00348 explicit fast_mutex_autolock(fast_mutex& __mtx) : _M_mtx(__mtx) 00349 { 00350 _M_mtx.lock(); 00351 } 00352 ~fast_mutex_autolock() 00353 { 00354 _M_mtx.unlock(); 00355 } 00356 private: 00357 fast_mutex_autolock(const fast_mutex_autolock&); 00358 fast_mutex_autolock& operator=(const fast_mutex_autolock&); 00359 }; 00360 00361 } // namespace memory 00362 } // namespace qx 00363 00364 #endif // _FAST_MUTEX_H 00365 #endif // _QX_USE_MEM_LEAK_DETECTION 00366 #endif // _QX_MODE_RELEASE 00367 #endif // QT_NO_DEBUG