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