00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024
00025
00026
00027
00028
00039 #ifndef _FAST_MUTEX_H
00040 #define _FAST_MUTEX_H
00041
00042 # if !defined(_NOTHREADS)
00043 # if !defined(_WIN32THREADS) && \
00044 (defined(_WIN32) && defined(_MT))
00045
00046
00047 # define _WIN32THREADS
00048 # elif !defined(_PTHREADS) && \
00049 defined(_REENTRANT)
00050
00051
00052
00053 # define _PTHREADS
00054 # endif
00055 # endif
00056
00057 # if !defined(_PTHREADS) && !defined(_WIN32THREADS) && !defined(_NOTHREADS)
00058 # define _NOTHREADS
00059 # endif
00060
00061 # if defined(_NOTHREADS)
00062 # if defined(_PTHREADS) || defined(_WIN32THREADS)
00063 # undef _NOTHREADS
00064 # error "Cannot define multi-threaded mode with -D_NOTHREADS"
00065 # if defined(__MINGW32__) && defined(_WIN32THREADS) && !defined(_MT)
00066 # error "Be sure to specify -mthreads with -D_WIN32THREADS"
00067 # endif
00068 # endif
00069 # endif
00070
00071 # ifndef _FAST_MUTEX_CHECK_INITIALIZATION
00072
00080 # define _FAST_MUTEX_CHECK_INITIALIZATION 1
00081 # endif
00082
00083 # if defined(_PTHREADS) && defined(_WIN32THREADS)
00084
00085
00086 # undef _PTHREADS
00087 # endif
00088
00089 # ifdef _DEBUG
00090 # include <stdio.h>
00091 # include <stdlib.h>
00093 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
00094 if (!(_Expr)) { \
00095 fprintf(stderr, "fast_mutex::%s\n", _Msg); \
00096 abort(); \
00097 }
00098 # else
00099
00100 # define _FAST_MUTEX_ASSERT(_Expr, _Msg) \
00101 ((void)0)
00102 # endif
00103
00104 # ifdef _PTHREADS
00105 # include <pthread.h>
00110 # define __VOLATILE volatile
00111
00115 class fast_mutex
00116 {
00117 pthread_mutex_t _M_mtx_impl;
00118 # if _FAST_MUTEX_CHECK_INITIALIZATION
00119 bool _M_initialized;
00120 # endif
00121 # ifdef _DEBUG
00122 bool _M_locked;
00123 # endif
00124 public:
00125 fast_mutex()
00126 # ifdef _DEBUG
00127 : _M_locked(false)
00128 # endif
00129 {
00130 ::pthread_mutex_init(&_M_mtx_impl, NULL);
00131 # if _FAST_MUTEX_CHECK_INITIALIZATION
00132 _M_initialized = true;
00133 # endif
00134 }
00135 ~fast_mutex()
00136 {
00137 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00138 # if _FAST_MUTEX_CHECK_INITIALIZATION
00139 _M_initialized = false;
00140 # endif
00141 ::pthread_mutex_destroy(&_M_mtx_impl);
00142 }
00143 void lock()
00144 {
00145 # if _FAST_MUTEX_CHECK_INITIALIZATION
00146 if (!_M_initialized)
00147 return;
00148 # endif
00149 ::pthread_mutex_lock(&_M_mtx_impl);
00150 # ifdef _DEBUG
00151
00152
00153
00154
00155
00156 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00157 _M_locked = true;
00158 # endif
00159 }
00160 void unlock()
00161 {
00162 # if _FAST_MUTEX_CHECK_INITIALIZATION
00163 if (!_M_initialized)
00164 return;
00165 # endif
00166 # ifdef _DEBUG
00167 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00168 _M_locked = false;
00169 # endif
00170 ::pthread_mutex_unlock(&_M_mtx_impl);
00171 }
00172 private:
00173 fast_mutex(const fast_mutex&);
00174 fast_mutex& operator=(const fast_mutex&);
00175 };
00176 # endif // _PTHREADS
00177
00178 # ifdef _WIN32THREADS
00179 # include <windows.h>
00184 # define __VOLATILE volatile
00185
00189 class fast_mutex
00190 {
00191 CRITICAL_SECTION _M_mtx_impl;
00192 # if _FAST_MUTEX_CHECK_INITIALIZATION
00193 bool _M_initialized;
00194 # endif
00195 # ifdef _DEBUG
00196 bool _M_locked;
00197 # endif
00198 public:
00199 fast_mutex()
00200 # ifdef _DEBUG
00201 : _M_locked(false)
00202 # endif
00203 {
00204 ::InitializeCriticalSection(&_M_mtx_impl);
00205 # if _FAST_MUTEX_CHECK_INITIALIZATION
00206 _M_initialized = true;
00207 # endif
00208 }
00209 ~fast_mutex()
00210 {
00211 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00212 # if _FAST_MUTEX_CHECK_INITIALIZATION
00213 _M_initialized = false;
00214 # endif
00215 ::DeleteCriticalSection(&_M_mtx_impl);
00216 }
00217 void lock()
00218 {
00219 # if _FAST_MUTEX_CHECK_INITIALIZATION
00220 if (!_M_initialized)
00221 return;
00222 # endif
00223 ::EnterCriticalSection(&_M_mtx_impl);
00224 # ifdef _DEBUG
00225 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00226 _M_locked = true;
00227 # endif
00228 }
00229 void unlock()
00230 {
00231 # if _FAST_MUTEX_CHECK_INITIALIZATION
00232 if (!_M_initialized)
00233 return;
00234 # endif
00235 # ifdef _DEBUG
00236 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00237 _M_locked = false;
00238 # endif
00239 ::LeaveCriticalSection(&_M_mtx_impl);
00240 }
00241 private:
00242 fast_mutex(const fast_mutex&);
00243 fast_mutex& operator=(const fast_mutex&);
00244 };
00245 # endif // _WIN32THREADS
00246
00247 # ifdef _NOTHREADS
00248
00252 # define __VOLATILE
00253
00257 class fast_mutex
00258 {
00259 # ifdef _DEBUG
00260 bool _M_locked;
00261 # endif
00262 public:
00263 fast_mutex()
00264 # ifdef _DEBUG
00265 : _M_locked(false)
00266 # endif
00267 {
00268 }
00269 ~fast_mutex()
00270 {
00271 _FAST_MUTEX_ASSERT(!_M_locked, "~fast_mutex(): still locked");
00272 }
00273 void lock()
00274 {
00275 # ifdef _DEBUG
00276 _FAST_MUTEX_ASSERT(!_M_locked, "lock(): already locked");
00277 _M_locked = true;
00278 # endif
00279 }
00280 void unlock()
00281 {
00282 # ifdef _DEBUG
00283 _FAST_MUTEX_ASSERT(_M_locked, "unlock(): not locked");
00284 _M_locked = false;
00285 # endif
00286 }
00287 private:
00288 fast_mutex(const fast_mutex&);
00289 fast_mutex& operator=(const fast_mutex&);
00290 };
00291 # endif // _NOTHREADS
00292
00294 class fast_mutex_autolock
00295 {
00296 fast_mutex& _M_mtx;
00297 public:
00298 explicit fast_mutex_autolock(fast_mutex& __mtx) : _M_mtx(__mtx)
00299 {
00300 _M_mtx.lock();
00301 }
00302 ~fast_mutex_autolock()
00303 {
00304 _M_mtx.unlock();
00305 }
00306 private:
00307 fast_mutex_autolock(const fast_mutex_autolock&);
00308 fast_mutex_autolock& operator=(const fast_mutex_autolock&);
00309 };
00310
00311 #endif // _FAST_MUTEX_H