log4tango 5.0.2
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
63namespace log4tango {
64
65namespace threading {
66
67std::string get_thread_id (void);
68
69long thread_id (void);
70
71//-----------------------------------------------------------------------------
72// Class : MSMutex
73//-----------------------------------------------------------------------------
75{
76public:
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
90private:
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
113private:
114 ScopedLock(const ScopedLock&);
115 ScopedLock operator=(const ScopedLock&);
116
117 LPCRITICAL_SECTION _criticalSection;
118};
119
120//-----------------------------------------------------------------------------
121// Class : RecursiveMutex
122//-----------------------------------------------------------------------------
124{
125public:
126 // ctor
127 RecursiveMutex (void) : recursion_level_(0) {
128 ::InitializeCriticalSection(&guard_);
129 }
130
131 // dtor
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
167protected:
168 // guards the <recursion level>
169 CRITICAL_SECTION guard_;
170
171private:
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
190template<typename T> class ThreadLocalDataHolder
191{
192public:
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
254private:
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
#define LOG4TANGO_EXPORT
Definition: Export.hh:38
Definition: MSThreads.hh:75
Mutex()
Definition: MSThreads.hh:78
LPCRITICAL_SECTION get_critical_section(void)
Definition: MSThreads.hh:86
~Mutex()
Definition: MSThreads.hh:82
Definition: MSThreads.hh:124
void unlock(void)
Definition: MSThreads.hh:153
~RecursiveMutex(void)
Definition: MSThreads.hh:132
RecursiveMutex(void)
Definition: MSThreads.hh:127
int lock(long timeout_=0)
Definition: MSThreads.hh:142
CRITICAL_SECTION guard_
Definition: MSThreads.hh:169
void unlockn(void)
Definition: MSThreads.hh:159
Definition: MSThreads.hh:101
ScopedLock(Mutex &mutex)
Definition: MSThreads.hh:104
~ScopedLock()
Definition: MSThreads.hh:109
int Mutex
Definition: DummyThreads.hh:41
std::string get_thread_id(void)
Definition: DummyThreads.cpp:37
Definition: Appender.hh:40