1 karl 1.3 //%2006////////////////////////////////////////////////////////////////////////
|
2 mike 1.2 //
3 // Copyright (c) 2000, 2001, 2002 BMC Software; Hewlett-Packard Development
4 // Company, L.P.; IBM Corp.; The Open Group; Tivoli Systems.
5 // Copyright (c) 2003 BMC Software; Hewlett-Packard Development Company, L.P.;
6 // IBM Corp.; EMC Corporation, The Open Group.
7 // Copyright (c) 2004 BMC Software; Hewlett-Packard Development Company, L.P.;
8 // IBM Corp.; EMC Corporation; VERITAS Software Corporation; The Open Group.
9 // Copyright (c) 2005 Hewlett-Packard Development Company, L.P.; IBM Corp.;
10 // EMC Corporation; VERITAS Software Corporation; The Open Group.
|
11 karl 1.3 // Copyright (c) 2006 Hewlett-Packard Development Company, L.P.; IBM Corp.;
12 // EMC Corporation; Symantec Corporation; The Open Group.
|
13 mike 1.2 //
14 // Permission is hereby granted, free of charge, to any person obtaining a copy
15 // of this software and associated documentation files (the "Software"), to
16 // deal in the Software without restriction, including without limitation the
17 // rights to use, copy, modify, merge, publish, distribute, sublicense, and/or
18 // sell copies of the Software, and to permit persons to whom the Software is
19 // furnished to do so, subject to the following conditions:
|
20 karl 1.3 //
|
21 mike 1.2 // THE ABOVE COPYRIGHT NOTICE AND THIS PERMISSION NOTICE SHALL BE INCLUDED IN
22 // ALL COPIES OR SUBSTANTIAL PORTIONS OF THE SOFTWARE. THE SOFTWARE IS PROVIDED
23 // "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT
24 // LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR
25 // PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
26 // HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN
27 // ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
28 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
29 //
30 //==============================================================================
31 //
32 //%/////////////////////////////////////////////////////////////////////////////
33
34 #ifndef Pegasus_Mutex_h
35 #define Pegasus_Mutex_h
36
37 #include <Pegasus/Common/Config.h>
38 #include <Pegasus/Common/Linkage.h>
|
39 mike 1.4 #include <Pegasus/Common/Magic.h>
|
40 mike 1.5 #include <Pegasus/Common/Threads.h>
|
41 mike 1.2
42 PEGASUS_NAMESPACE_BEGIN
43
|
44 mike 1.5 //==============================================================================
45 //
46 // MutexRep
47 //
48 //==============================================================================
49
50 #if defined(PEGASUS_HAVE_PTHREADS)
51 typedef pthread_mutex_t MutexType;
52 inline void mutex_lock(MutexType* mutex) { pthread_mutex_lock(mutex); }
53 inline void mutex_unlock(MutexType* mutex) { pthread_mutex_unlock(mutex); }
54 struct MutexRep
55 {
56 pthread_mutex_t mutex;
57 int count;
58 };
59 # define PEGASUS_MUTEX_INITIALIZER PTHREAD_MUTEX_INITIALIZER
60 #endif
61
62 #if defined(PEGASUS_HAVE_WINDOWS_THREADS)
63 typedef HANDLE MutexType;
64 inline void mutex_lock(MutexType* m) { WaitForSingleObject(*m, INFINITE); }
65 mike 1.5 inline void mutex_unlock(MutexType* m) { ReleaseMutex(*m); }
66 struct MutexRep
67 {
68 MutexType handle;
69 size_t count;
70 };
71 # define PEGASUS_MUTEX_INITIALIZER (CreateMutex(NULL, FALSE, NULL))
72 #endif
73
74 //==============================================================================
75 //
76 // Mutex
77 //
78 //==============================================================================
79
|
80 mike 1.2 class PEGASUS_COMMON_LINKAGE Mutex
81 {
82 public:
83
|
84 mike 1.6 enum RecursiveTag { RECURSIVE };
85 enum NonRecursiveTag { NON_RECURSIVE };
86
87 /** Default constructor creates a recursive mutex.
88 */
|
89 mike 1.2 Mutex();
90
|
91 mike 1.6 /** Call as Mutex(Mutex::RECURSIVE) to create a recursive mutex.
92 */
93 Mutex(RecursiveTag);
94
95 /** Call as Mutex(Mutex::NON_RECURSIVE) to create a non-recursive mutex.
96 */
97 Mutex(NonRecursiveTag);
98
|
99 mike 1.2 ~Mutex();
100
|
101 mike 1.5 void lock();
102
|
103 kumpf 1.13 /**
104 Attempts to lock the mutex without blocking.
105 @return A Boolean indicating whether the lock was acquired.
106 */
107 Boolean try_lock();
|
108 mike 1.5
|
109 kumpf 1.12 /**
110 Attempts to lock the mutex within the specified time.
111 @param milliseconds The maximum time to block while attempting to
112 acquire the lock.
113 @return A Boolean indicating whether the lock was acquired.
114 */
115 Boolean timed_lock(Uint32 milliseconds);
|
116 mike 1.2
117 void unlock();
118
|
119 thilo.boehm 1.16 #if defined(PEGASUS_OS_LINUX)
|
120 kumpf 1.9 /**
121 This method must only be called after a fork() to reset the mutex
122 lock status in the new process. Any other use of this method is
123 unsafe.
124 */
125 void reinitialize();
126 #endif
127
|
128 mike 1.5 private:
129 Mutex(const Mutex&);
130 Mutex& operator=(const Mutex&);
131
132 MutexRep _rep;
133 Magic<0x57D11485> _magic;
134
135 friend class Condition;
136 };
|
137 mike 1.2
|
138 mike 1.5 //==============================================================================
139 //
140 // AutoMutex
141 //
142 //==============================================================================
143
144 class PEGASUS_COMMON_LINKAGE AutoMutex
145 {
146 public:
147
148 AutoMutex(Mutex& mutex) : _mutex(mutex)
|
149 mike 1.2 {
|
150 mike 1.5 _mutex.lock();
|
151 mike 1.2 }
152
|
153 mike 1.5 ~AutoMutex()
154 {
155 _mutex.unlock();
156 }
|
157 mike 1.2
|
158 mike 1.5 private:
159 AutoMutex(); // Unimplemented
160 AutoMutex(const AutoMutex& x); // Unimplemented
161 AutoMutex& operator=(const AutoMutex& x); // Unimplemented
|
162 mike 1.4
|
163 mike 1.5 Mutex& _mutex;
|
164 mike 1.2 };
165
|
166 kumpf 1.9 //==============================================================================
167 //
168 // PEGASUS_FORK_SAFE_MUTEX
169 //
170 //==============================================================================
171
172 // Use of this macro ensures that a static Mutex is not locked across a fork().
173
174 #if !defined(PEGASUS_HAVE_PTHREADS) || \
|
175 thilo.boehm 1.16 defined(PEGASUS_OS_ZOS) || \
|
176 kumpf 1.9 defined(PEGASUS_OS_VMS)
177
178 # define PEGASUS_FORK_SAFE_MUTEX(mutex)
179
|
180 thilo.boehm 1.16 #elif defined(PEGASUS_OS_LINUX)
|
181 kumpf 1.9
182 # define PEGASUS_FORK_SAFE_MUTEX(mutex) \
183 class ForkSafeMutex ## mutex \
184 { \
185 public: \
186 ForkSafeMutex ## mutex() \
187 { \
188 pthread_atfork( \
189 0, \
190 0, \
191 _reinitializeMutex); \
192 } \
193 \
194 private: \
195 static void _reinitializeMutex() \
196 { \
197 mutex.reinitialize(); \
198 } \
199 }; \
200 \
201 static ForkSafeMutex ## mutex __forkSafeMutex ## mutex;
202 kumpf 1.9
203 #else
204
205 # define PEGASUS_FORK_SAFE_MUTEX(mutex) \
206 class ForkSafeMutex ## mutex \
207 { \
208 public: \
209 ForkSafeMutex ## mutex() \
210 { \
211 pthread_atfork( \
212 _lockMutex, \
213 _unlockMutex, \
214 _unlockMutex); \
215 } \
216 \
217 private: \
218 static void _lockMutex() \
219 { \
220 mutex.lock(); \
221 } \
222 \
223 kumpf 1.9 static void _unlockMutex() \
224 { \
225 mutex.unlock(); \
226 } \
227 }; \
228 \
229 static ForkSafeMutex ## mutex __forkSafeMutex ## mutex;
230
231 #endif
232
|
233 mike 1.2 PEGASUS_NAMESPACE_END
234
235 #endif /* Pegasus_Mutex_h */
|