blocxx
MutexImpl.cpp
Go to the documentation of this file.
1/*******************************************************************************
2* Copyright (C) 2005, Vintela, Inc. All rights reserved.
3* Copyright (C) 2006, Novell, Inc. All rights reserved.
4*
5* Redistribution and use in source and binary forms, with or without
6* modification, are permitted provided that the following conditions are met:
7*
8* * Redistributions of source code must retain the above copyright notice,
9* this list of conditions and the following disclaimer.
10* * Redistributions in binary form must reproduce the above copyright
11* notice, this list of conditions and the following disclaimer in the
12* documentation and/or other materials provided with the distribution.
13* * Neither the name of
14* Vintela, Inc.,
15* nor Novell, Inc.,
16* nor the names of its contributors or employees may be used to
17* endorse or promote products derived from this software without
18* specific prior written permission.
19*
20* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
30* POSSIBILITY OF SUCH DAMAGE.
31*******************************************************************************/
32
33
39#include "blocxx/BLOCXX_config.h"
40#include "blocxx/MutexImpl.hpp"
41#include <cerrno>
42#include <cassert>
43
44namespace BLOCXX_NAMESPACE
45{
46
47namespace MutexImpl
48{
49
50#if defined (BLOCXX_USE_PTHREAD)
51
52#if !defined (BLOCXX_NCR)
53
59int
61{
64 assert(res == 0);
65 if (res != 0)
66 {
67 return -1;
68 }
69
70#if defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
72 assert(res == 0);
73 if (res != 0)
74 {
76 return -1;
77 }
78#endif
79
82 if (res != 0)
83 {
84 return -1;
85 }
86
87#if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
89 if (res != 0)
90 {
92 return -1;
93 }
94
95 handle.valid_id = false;
96 handle.count = 0;
97#endif
98 return 0;
99}
100
101#else //#if !defined (BLOCXX_NCR)
102
103int
105{
108 assert(res == 0);
109 if (res != 0)
110 {
111 return -1;
112 }
113
114#if defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
116 assert(res == 0);
117 if (res != 0)
118 {
120 return -1;
121 }
122#endif
123
125
127 if (res != 0)
128 {
129 return -1;
130 }
131
132#if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
134 if (res != 0)
135 {
137 return -1;
138 }
139
140 handle.valid_id = false;
141 handle.count = 0;
142#endif
143 return 0;
144}
145
146#endif //#ifndef BLOCXX_NCR
147
157int
159{
160 switch (pthread_mutex_destroy(&handle.mutex))
161 {
162 case 0:
163 break;
164 case EBUSY:
165 return -1;
166 break;
167 default:
168 return -2;
169 }
170 int res = 0;
171#if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
172 res = pthread_cond_destroy(&handle.unlocked);
173 assert(res == 0);
174#endif
175 return res;
176}
177
186int
188{
189 int res = pthread_mutex_lock(&handle.mutex);
190 assert(res == 0);
191
192#if !defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
194 if (handle.valid_id && pthread_equal(handle.thread_id, tid))
195 {
196 ++handle.count;
197 }
198 else
199 {
200 while (handle.valid_id)
201 {
202 res = pthread_cond_wait(&handle.unlocked, &handle.mutex);
203 assert(res == 0 || res == EINTR);
204 if (res == EINTR)
205 {
206 try
207 {
209 }
210 catch (...)
211 {
213 throw;
214 }
215 }
216 }
217
218 handle.thread_id = tid;
219 handle.valid_id = true;
220 handle.count = 1;
221 }
222
224 assert(res == 0);
225#endif
226 return res;
227}
228
235int
237{
238#if defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
239 int res = pthread_mutex_unlock(&handle.mutex);
240 assert(res == 0);
241 return res;
242#else
243 int res = 0;
244 res = pthread_mutex_lock(&handle.mutex);
245 assert(res == 0);
246
248 if (handle.valid_id && !pthread_equal(handle.thread_id, tid))
249 {
251 assert(res == 0);
252 return -1;
253 }
254
255 if (--handle.count == 0)
256 {
257 assert(handle.valid_id);
258 handle.valid_id = false;
259
260 res = pthread_cond_signal(&handle.unlocked);
261 assert(res == 0);
262 }
263
265 assert(res == 0);
266 return res;
267#endif //#if defined(BLOCXX_HAVE_PTHREAD_MUTEXATTR_SETTYPE)
268}
269
270#endif //#if defined (BLOCXX_USE_PTHREAD)
271
272#if defined(BLOCXX_WIN32)
273
274int
276{
278 assert(handle);
280 return 0;
281}
282
283int
285{
286 if(handle)
287 {
289 delete handle;
290 handle = 0;
291 }
292 return 0;
293}
294
295int
297{
299 return 0;
300}
301
302int
304{
306 return 0;
307}
308
309#endif //#if defined(BLOCXX_WIN32)
310
311} // end namespace MutexImpl
312} // end namespace BLOCXX_NAMESPACE
313
static void testCancel()
Test if this thread has been cancelled.
Definition Thread.cpp:432
BLOCXX_COMMON_API int acquireMutex(Mutex_t &handle)
Acquire the mutex specified by a given mutex handle.
BLOCXX_COMMON_API int destroyMutex(Mutex_t &handle)
Destroy a mutex previously created with createMutex.
BLOCXX_COMMON_API int releaseMutex(Mutex_t &handle)
Release a mutex that was previously acquired with the acquireMutex method.
BLOCXX_COMMON_API int createMutex(Mutex_t &handle)
Create a platform specific mutext handle.
Taken from RFC 1321.
bool operator==(const Array< T > &x, const Array< T > &y)