log4tango  5.0.1
MSThreads.hh
Go to the documentation of this file.
1 //
2 // MSThreads.hh
3 //
4 // Copyright (C) : 2000 - 2002
5 // LifeLine Networks BV (www.lifeline.nl). All rights reserved.
6 // Bastiaan Bakker. All rights reserved.
7 //
8 // 2004,2005,2006,2007,2008,2009,2010,2011,2012
9 // Synchrotron SOLEIL
10 // L'Orme des Merisiers
11 // Saint-Aubin - BP 48 - France
12 //
13 // This file is part of log4tango.
14 //
15 // Log4ango is free software: you can redistribute it and/or modify
16 // it under the terms of the GNU Lesser General Public License as published by
17 // the Free Software Foundation, either version 3 of the License, or
18 // (at your option) any later version.
19 //
20 // Log4tango is distributed in the hope that it will be useful,
21 // but WITHOUT ANY WARRANTY; without even the implied warranty of
22 // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
23 // GNU Lesser General Public License for more details.
24 //
25 // You should have received a copy of the GNU Lesser General Public License
26 // along with Log4Tango. If not, see <http://www.gnu.org/licenses/>.
27 
28 #ifndef _LOG4TANGO_THREADING_MSTHREADS_H
29 #define _LOG4TANGO_THREADING_MSTHREADS_H
30 
31 #include <string>
32 
33 // deal with ERROR #define
34 
35 // This #includes windows.h with NOGDI and WIN32_LEAN_AND_MEAN
36 // #defined. If this is not what the user wants, #include
37 // windows.h before this file.
38 
39 #ifndef _WINDOWS_
40 # ifndef NOGDI
41 # define NOGDI // circumvent the ERROR #define in windows.h
42 # define LOG4TANGO_UNDEFINE_NOGDI
43 # endif
44 
45 # ifndef WIN32_LEAN_AND_MEAN
46 # define WIN32_LEAN_AND_MEAN
47 # define LOG4TANGO_UNDEFINE_WIN32_LEAN_AND_MEAN
48 # endif
49 
50 # include <windows.h>
51 
52 # ifdef LOG4TANGO_UNDEFINE_NOGDI
53 # undef NOGDI
54 # endif
55 
56 # ifdef LOG4TANGO_UNDEFINE_WIN32_LEAN_AND_MEAN
57 # undef WIN32_LEAN_AND_MEAN
58 # endif
59 
60 #endif
61 // done dealing with ERROR #define
62 
63 namespace log4tango {
64 
65 namespace threading {
66 
67 std::string get_thread_id (void);
68 
69 long thread_id (void);
70 
71 //-----------------------------------------------------------------------------
72 // Class : MSMutex
73 //-----------------------------------------------------------------------------
75 {
76 public:
77 
78  Mutex() {
79  InitializeCriticalSection(&_criticalSection);
80  }
81 
82  ~Mutex() {
83  DeleteCriticalSection(&_criticalSection);
84  }
85 
86  inline LPCRITICAL_SECTION get_critical_section (void) {
87  return &_criticalSection;
88  }
89 
90 private:
91  Mutex(const Mutex&);
92  Mutex operator=(const Mutex&);
93 
94  CRITICAL_SECTION _criticalSection;
95 };
96 
97 //-----------------------------------------------------------------------------
98 // Class : ScopedLock
99 //-----------------------------------------------------------------------------
101 {
102  public:
103 
104  ScopedLock (Mutex& mutex) {
105  _criticalSection = mutex.get_critical_section();
106  EnterCriticalSection(_criticalSection);
107  }
108 
110  LeaveCriticalSection(_criticalSection);
111  }
112 
113 private:
114  ScopedLock(const ScopedLock&);
115  ScopedLock operator=(const ScopedLock&);
116 
117  LPCRITICAL_SECTION _criticalSection;
118 };
119 
120 //-----------------------------------------------------------------------------
121 // Class : RecursiveMutex
122 //-----------------------------------------------------------------------------
124 {
125 public:
126  // ctor
127  RecursiveMutex (void) : recursion_level_(0) {
128  ::InitializeCriticalSection(&guard_);
129  }
130 
131  // dtor
132  ~RecursiveMutex (void) {
133  ::DeleteCriticalSection(&guard_);
134  }
135 
136  // Locking an RecursiveMutex:
137  // If <timeout_> is null (the default), <lock> blocks until
138  // the mutex is acquired and returns 1 (true). Otherwise,
139  // <lock> blocks until the mutex is acquired or times out
140  // after <timeout_> milliseconds in which case 0 (false) is
141  // returned.
142  inline int lock (long timeout_ = 0) {
143  ::EnterCriticalSection(&guard_);
144  recursion_level_++;
145  return 0;
146  }
147 
148  // Releasing an RecursiveMutex:
149  // Call unlock <recursion level> times (i.e. one call for
150  // each previous call to lock) or call unlockn just once.
151  // These two methods do nothing if the caller is not the
152  // current owner of the mutex.
153  inline void unlock (void) {
154  //-should work if called by owner
155  recursion_level_--;
156  ::LeaveCriticalSection(&guard_);
157  }
158 
159  inline void unlockn (void) {
160  //-should work if called by owner
161  while (recursion_level_ > 0) {
162  recursion_level_--;
163  ::LeaveCriticalSection(&guard_);
164  }
165  }
166 
167 protected:
168  // guards the <recursion level>
169  CRITICAL_SECTION guard_;
170 
171 private:
172  // current level of the recursion
173  unsigned long recursion_level_;
174 
175  // dummy copy constructor and operator= to prevent copying
177  RecursiveMutex& operator= (const RecursiveMutex&);
178 };
179 
180 //-----------------------------------------------------------------------------
181 // Class : ThreadLocalDataHolder
182 //-----------------------------------------------------------------------------
189 #ifdef LOG4TANGO_HAS_NDC
190 template<typename T> class ThreadLocalDataHolder
191 {
192 public:
193 
194  inline ThreadLocalDataHolder()
195  : _key(TlsAlloc()) {
196  };
197 
198  inline ~ThreadLocalDataHolder() {
199  TlsFree(_key);
200  };
201 
207  inline T* get (void) const {
208  return (T*)TlsGetValue(_key);
209  };
210 
217  inline T* operator->() const {
218  return get();
219  };
220 
226  inline T& operator*() const {
227  return *get();
228  };
229 
236  inline T* release() {
237  T* result = (T*)TlsGetValue(_key);
238  TlsSetValue(_key, NULL);
239  return result;
240  };
241 
248  inline void reset(T* p = NULL) {
249  T* thing = (T*)TlsGetValue(_key);
250  delete thing;
251  TlsSetValue(_key, p);
252  };
253 
254 private:
255 
256  DWORD _key;
257 };
258 
259 #endif // LOG4TANGO_HAS_NDC
260 
261 } // namespace threading
262 
263 } // namespace log4tango
264 
265 #endif // _LOG4TANGO_THREADING_MSTHREADS_H
Definition: Appender.hh:40
Definition: MSThreads.hh:100
#define LOG4TANGO_EXPORT
Definition: Export.hh:38
Definition: MSThreads.hh:123
int Mutex
Definition: DummyThreads.hh:41
ScopedLock(Mutex &mutex)
Definition: MSThreads.hh:104
LPCRITICAL_SECTION get_critical_section(void)
Definition: MSThreads.hh:86
int ScopedLock
Definition: DummyThreads.hh:43
CRITICAL_SECTION guard_
Definition: MSThreads.hh:169
~Mutex()
Definition: MSThreads.hh:82
Mutex()
Definition: MSThreads.hh:78
int lock(long timeout_=0)
Definition: MSThreads.hh:142
~ScopedLock()
Definition: MSThreads.hh:109
~RecursiveMutex(void)
Definition: MSThreads.hh:132
std::string get_thread_id(void)
Definition: DummyThreads.cpp:37
RecursiveMutex(void)
Definition: MSThreads.hh:127
void unlock(void)
Definition: MSThreads.hh:153
void unlockn(void)
Definition: MSThreads.hh:159
Definition: MSThreads.hh:74