| QxOrm 1.2.5 C++ Object Relational Mapping library

- Main Page
- Modules
- Namespaces
- Classes
- Files
- Directories

- File List
- File Members

fast_mutex.h
Go to the documentation of this file.

    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 NDEBUG
    00041 #ifndef QT_NO_DEBUG
    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 NDEBUG
    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 // NDEBUG
    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 NDEBUG
    00135 #ifndef QT_NO_DEBUG
    00136         bool _M_locked;
    00137 #endif // QT_NO_DEBUG
    00138 #endif // NDEBUG
    00139     public:
    00140         fast_mutex()
    00141 #ifndef NDEBUG
    00142 #ifndef QT_NO_DEBUG
    00143             : _M_locked(false)
    00144 #endif // QT_NO_DEBUG
    00145 #endif // NDEBUG
    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 NDEBUG
    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 // NDEBUG
    00178         }
    00179         void unlock()
    00180         {
    00181 #       if _FAST_MUTEX_CHECK_INITIALIZATION
    00182             if (!_M_initialized)
    00183                 return;
    00184 #       endif
    00185 #ifndef NDEBUG
    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 // NDEBUG
    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 NDEBUG
    00221 #ifndef QT_NO_DEBUG
    00222         bool _M_locked;
    00223 #endif // QT_NO_DEBUG
    00224 #endif // NDEBUG
    00225     public:
    00226         fast_mutex()
    00227 #ifndef NDEBUG
    00228 #ifndef QT_NO_DEBUG
    00229             : _M_locked(false)
    00230 #endif // QT_NO_DEBUG
    00231 #endif // NDEBUG
    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 NDEBUG
    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 // NDEBUG
    00259         }
    00260         void unlock()
    00261         {
    00262 #       if _FAST_MUTEX_CHECK_INITIALIZATION
    00263             if (!_M_initialized)
    00264                 return;
    00265 #       endif
    00266 #ifndef NDEBUG
    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 // NDEBUG
    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 NDEBUG
    00297 #ifndef QT_NO_DEBUG
    00298         bool _M_locked;
    00299 #endif // QT_NO_DEBUG
    00300 #endif // NDEBUG
    00301     public:
    00302         fast_mutex()
    00303 #ifndef NDEBUG
    00304 #ifndef QT_NO_DEBUG
    00305             : _M_locked(false)
    00306 #endif // QT_NO_DEBUG
    00307 #endif // NDEBUG
    00308         {
    00309         }
    00310         ~fast_mutex()
    00311         {
    00312             _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
    00313         }
    00314         void lock()
    00315         {
    00316 #ifndef NDEBUG
    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 // NDEBUG
    00322         }
    00323         void unlock()
    00324         {
    00325 #ifndef NDEBUG
    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 // NDEBUG
    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 // QT_NO_DEBUG
    00367 #endif // NDEBUG