1 /* === S Y N F I G ========================================================= */
2 /*! \file mutex.cpp
3 ** \brief Template File
4 **
5 ** $Id$
6 **
7 ** \legal
8 ** Copyright (c) 2002-2005 Robert B. Quattlebaum Jr., Adrian Bentley
9 **
10 ** This package is free software; you can redistribute it and/or
11 ** modify it under the terms of the GNU General Public License as
12 ** published by the Free Software Foundation; either version 2 of
13 ** the License, or (at your option) any later version.
14 **
15 ** This package is distributed in the hope that it will be useful,
16 ** but WITHOUT ANY WARRANTY; without even the implied warranty of
17 ** MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
18 ** General Public License for more details.
19 ** \endlegal
20 */
21 /* ========================================================================= */
22
23 /* === H E A D E R S ======================================================= */
24
25 #ifdef USING_PCH
26 # include "pch.h"
27 #else
28 #ifdef HAVE_CONFIG_H
29 # include <config.h>
30 #endif
31
32 #include "mutex.h"
33
34 #ifdef HAVE_LIBPTHREAD
35 #define USING_PTHREADS 1
36 #else
37 #ifdef _WIN32
38 #define USING_WIN32_THREADS 1
39 #else
40 #error Need either libpthread of win32 threads
41 #endif
42 #endif
43
44 #ifdef USING_WIN32_THREADS
45 #include <windows.h>
46 #endif
47
48 #ifdef USING_PTHREADS
49 #include <pthread.h>
50 #endif
51
52 #endif
53
54 /* === U S I N G =========================================================== */
55
56 //using namespace std;
57 //using namespace etl;
58 using namespace synfig;
59
60 /* === M A C R O S ========================================================= */
61
62 /* === G L O B A L S ======================================================= */
63
64 /* === P R O C E D U R E S ================================================= */
65
66 /* === M E T H O D S ======================================================= */
67
68
69
70
71
72
73 bool
is_locked()74 Mutex::is_locked()
75 {
76 if(try_lock())
77 {
78 unlock();
79 return false;
80 }
81 return true;
82 }
83
84 void
unlock_all()85 RecMutex::unlock_all()
86 {
87 while(is_locked()) unlock();
88 }
89
90 #ifdef USING_PTHREADS
Mutex()91 Mutex::Mutex()
92 {
93 pthread_mutex_t*const mtx_ptr(new pthread_mutex_t);
94
95 pthread_mutexattr_t attr;
96 pthread_mutexattr_init(&attr);
97
98 //#ifdef PTHREAD_PRIO_INHERIT
99 //pthread_mutexattr_setprioceiling(&attr,PTHREAD_PRIO_INHERIT);
100 //#endif
101
102 //#ifdef PTHREAD_MUTEX_RECURSIVE
103 //pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
104 //#endif
105
106 pthread_mutex_init(mtx_ptr,&attr);
107 pthread_mutexattr_destroy(&attr);
108
109 blackbox=mtx_ptr;
110 }
111
~Mutex()112 Mutex::~Mutex()
113 {
114 pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
115 pthread_mutex_destroy(mtx_ptr);
116 delete mtx_ptr;
117 }
118
119 void
lock()120 Mutex::lock()
121 {
122 pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
123 pthread_mutex_lock(mtx_ptr);
124 }
125
126 void
unlock()127 Mutex::unlock()
128 {
129 pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
130 pthread_mutex_unlock(mtx_ptr);
131 }
132
133 bool
try_lock()134 Mutex::try_lock()
135 {
136 pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
137 return !(bool) pthread_mutex_trylock(mtx_ptr);
138 }
139
140
RecMutex()141 RecMutex::RecMutex()
142 {
143 pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
144 pthread_mutexattr_t attr;
145
146 // Backtrack and get rid of the non-recursive mutex
147 pthread_mutex_destroy(mtx_ptr);
148
149 pthread_mutexattr_init(&attr);
150
151 pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
152
153 pthread_mutex_init(mtx_ptr,&attr);
154 pthread_mutexattr_destroy(&attr);
155 }
156
157
158
RWLock()159 RWLock::RWLock()
160 {
161 pthread_rwlock_t*const rwlock_ptr(new pthread_rwlock_t);
162
163 pthread_rwlock_init(rwlock_ptr, NULL);
164
165 blackbox=rwlock_ptr;
166 }
167
~RWLock()168 RWLock::~RWLock()
169 {
170 pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
171
172 pthread_rwlock_destroy(rwlock_ptr);
173
174 delete rwlock_ptr;
175 }
176
177 void
reader_lock()178 RWLock::reader_lock()
179 {
180 pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
181
182 pthread_rwlock_rdlock(rwlock_ptr);
183 }
184
185 void
reader_unlock()186 RWLock::reader_unlock()
187 {
188 pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
189
190 pthread_rwlock_unlock(rwlock_ptr);
191 }
192
193 bool
reader_trylock()194 RWLock::reader_trylock()
195 {
196 pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
197
198 return !pthread_rwlock_tryrdlock(rwlock_ptr);
199 }
200
201 void
writer_lock()202 RWLock::writer_lock()
203 {
204 pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
205
206 pthread_rwlock_wrlock(rwlock_ptr);
207 }
208
209 void
writer_unlock()210 RWLock::writer_unlock()
211 {
212 pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
213
214 pthread_rwlock_unlock(rwlock_ptr);
215 }
216
217 bool
writer_trylock()218 RWLock::writer_trylock()
219 {
220 pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
221
222 return !pthread_rwlock_trywrlock(rwlock_ptr);
223 }
224
225 #endif
226
227 #ifdef USING_WIN32_THREADS
Mutex()228 Mutex::Mutex()
229 {
230 HANDLE& mtx(*reinterpret_cast<HANDLE*>(&blackbox));
231 mtx=CreateMutex(NULL, FALSE, NULL);
232 }
233
~Mutex()234 Mutex::~Mutex()
235 {
236 HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
237 CloseHandle(mtx);
238 }
239
240 void
lock()241 Mutex::lock()
242 {
243 HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
244 WaitForSingleObject(mtx, INFINITE);
245 }
246
247 void
unlock()248 Mutex::unlock()
249 {
250 HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
251 ReleaseMutex(mtx);
252 }
253
254 bool
try_lock()255 Mutex::try_lock()
256 {
257 HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
258 return WaitForSingleObject(mtx, 0)==WAIT_FAILED;
259 }
260
261
RecMutex()262 RecMutex::RecMutex()
263 {
264 // Win32 mutexes are recursive by default.
265 }
266
267
RWLock()268 RWLock::RWLock()
269 {
270 }
271
~RWLock()272 RWLock::~RWLock()
273 {
274 }
275
276 void
reader_lock()277 RWLock::reader_lock()
278 {
279 }
280
281 void
reader_unlock()282 RWLock::reader_unlock()
283 {
284 }
285
286 bool
reader_trylock()287 RWLock::reader_trylock()
288 {
289 }
290
291 void
writer_lock()292 RWLock::writer_lock()
293 {
294 }
295
296 void
writer_unlock()297 RWLock::writer_unlock()
298 {
299 }
300
301 bool
writer_trylock()302 RWLock::writer_trylock()
303 {
304 }
305
306 #endif
307