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 #ifndef _LOG4TANGO_THREADING_MSTHREADS_H
00029 #define _LOG4TANGO_THREADING_MSTHREADS_H
00030
00031 #include <string>
00032
00033
00034
00035
00036
00037
00038
00039 #ifndef _WINDOWS_
00040 # ifndef NOGDI
00041 # define NOGDI // circumvent the ERROR #define in windows.h
00042 # define LOG4TANGO_UNDEFINE_NOGDI
00043 # endif
00044
00045 # ifndef WIN32_LEAN_AND_MEAN
00046 # define WIN32_LEAN_AND_MEAN
00047 # define LOG4TANGO_UNDEFINE_WIN32_LEAN_AND_MEAN
00048 # endif
00049
00050 # include <windows.h>
00051
00052 # ifdef LOG4TANGO_UNDEFINE_NOGDI
00053 # undef NOGDI
00054 # endif
00055
00056 # ifdef LOG4TANGO_UNDEFINE_WIN32_LEAN_AND_MEAN
00057 # undef WIN32_LEAN_AND_MEAN
00058 # endif
00059
00060 #endif
00061
00062
00063 namespace log4tango {
00064
00065 namespace threading {
00066
00067 std::string get_thread_id (void);
00068
00069 long thread_id (void);
00070
00071
00072
00073
00074 class LOG4TANGO_EXPORT Mutex
00075 {
00076 public:
00077
00078 Mutex() {
00079 InitializeCriticalSection(&_criticalSection);
00080 }
00081
00082 ~Mutex() {
00083 DeleteCriticalSection(&_criticalSection);
00084 }
00085
00086 inline LPCRITICAL_SECTION get_critical_section (void) {
00087 return &_criticalSection;
00088 }
00089
00090 private:
00091 Mutex(const Mutex&);
00092 Mutex operator=(const Mutex&);
00093
00094 CRITICAL_SECTION _criticalSection;
00095 };
00096
00097
00098
00099
00100 class ScopedLock
00101 {
00102 public:
00103
00104 ScopedLock (Mutex& mutex) {
00105 _criticalSection = mutex.get_critical_section();
00106 EnterCriticalSection(_criticalSection);
00107 }
00108
00109 ~ScopedLock() {
00110 LeaveCriticalSection(_criticalSection);
00111 }
00112
00113 private:
00114 ScopedLock(const ScopedLock&);
00115 ScopedLock operator=(const ScopedLock&);
00116
00117 LPCRITICAL_SECTION _criticalSection;
00118 };
00119
00120
00121
00122
00123 class RecursiveMutex
00124 {
00125 public:
00126
00127 RecursiveMutex (void) : recursion_level_(0) {
00128 ::InitializeCriticalSection(&guard_);
00129 }
00130
00131
00132 ~RecursiveMutex (void) {
00133 ::DeleteCriticalSection(&guard_);
00134 }
00135
00136
00137
00138
00139
00140
00141
00142 inline int lock (long timeout_ = 0) {
00143 ::EnterCriticalSection(&guard_);
00144 recursion_level_++;
00145 return 0;
00146 }
00147
00148
00149
00150
00151
00152
00153 inline void unlock (void) {
00154
00155 recursion_level_--;
00156 ::LeaveCriticalSection(&guard_);
00157 }
00158
00159 inline void unlockn (void) {
00160
00161 while (recursion_level_ > 0) {
00162 recursion_level_--;
00163 ::LeaveCriticalSection(&guard_);
00164 }
00165 }
00166
00167 protected:
00168
00169 CRITICAL_SECTION guard_;
00170
00171 private:
00172
00173 unsigned long recursion_level_;
00174
00175
00176 RecursiveMutex (const RecursiveMutex&);
00177 RecursiveMutex& operator= (const RecursiveMutex&);
00178 };
00179
00180
00181
00182
00189 #ifdef LOG4TANGO_HAS_NDC
00190 template<typename T> class ThreadLocalDataHolder
00191 {
00192 public:
00193
00194 inline ThreadLocalDataHolder()
00195 : _key(TlsAlloc()) {
00196 };
00197
00198 inline ~ThreadLocalDataHolder() {
00199 TlsFree(_key);
00200 };
00201
00207 inline T* get (void) const {
00208 return (T*)TlsGetValue(_key);
00209 };
00210
00217 inline T* operator->() const {
00218 return get();
00219 };
00220
00226 inline T& operator*() const {
00227 return *get();
00228 };
00229
00236 inline T* release() {
00237 T* result = (T*)TlsGetValue(_key);
00238 TlsSetValue(_key, NULL);
00239 return result;
00240 };
00241
00248 inline void reset(T* p = NULL) {
00249 T* thing = (T*)TlsGetValue(_key);
00250 delete thing;
00251 TlsSetValue(_key, p);
00252 };
00253
00254 private:
00255
00256 DWORD _key;
00257 };
00258
00259 #endif // LOG4TANGO_HAS_NDC
00260
00261 }
00262
00263 }
00264
00265 #endif // _LOG4TANGO_THREADING_MSTHREADS_H