Use a mutex to prevent the two render threads (rendering the workarea and the navigat...
[synfig.git] / synfig-core / trunk / src / synfig / mutex.cpp
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 #endif
40 #endif
41
42 #ifdef USING_WIN32_THREADS
43 #include <windows.h>
44 #endif
45
46 #ifdef USING_PTHREADS
47 #include <pthread.h>
48 #endif
49
50 #endif
51
52 /* === U S I N G =========================================================== */
53
54 //using namespace std;
55 //using namespace etl;
56 using namespace synfig;
57
58 /* === M A C R O S ========================================================= */
59
60 /* === G L O B A L S ======================================================= */
61
62 /* === P R O C E D U R E S ================================================= */
63
64 /* === M E T H O D S ======================================================= */
65
66
67
68
69
70
71 bool
72 Mutex::is_locked()
73 {
74         if(try_lock())
75         {
76                 unlock();
77                 return false;
78         }
79         return true;
80 }
81
82 void
83 RecMutex::unlock_all()
84 {
85         while(is_locked()) unlock();
86 }
87
88 #ifdef USING_PTHREADS
89 Mutex::Mutex()
90 {
91         pthread_mutex_t*const mtx_ptr(new pthread_mutex_t);
92
93         pthread_mutexattr_t attr;
94         pthread_mutexattr_init(&attr);
95
96         //#ifdef PTHREAD_PRIO_INHERIT
97         //pthread_mutexattr_setprioceiling(&attr,PTHREAD_PRIO_INHERIT);
98         //#endif
99
100         //#ifdef PTHREAD_MUTEX_RECURSIVE
101         //pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
102         //#endif
103
104         pthread_mutex_init(mtx_ptr,&attr);
105         pthread_mutexattr_destroy(&attr);
106
107         blackbox=mtx_ptr;
108 }
109
110 Mutex::~Mutex()
111 {
112         pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
113         pthread_mutex_destroy(mtx_ptr);
114         delete mtx_ptr;
115 }
116
117 void
118 Mutex::lock()
119 {
120         pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
121         pthread_mutex_lock(mtx_ptr);
122 }
123
124 void
125 Mutex::unlock()
126 {
127         pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
128         pthread_mutex_unlock(mtx_ptr);
129 }
130
131 bool
132 Mutex::try_lock()
133 {
134         pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
135         return !(bool) pthread_mutex_trylock(mtx_ptr);
136 }
137
138
139 RecMutex::RecMutex()
140 {
141         pthread_mutex_t*const mtx_ptr(static_cast<pthread_mutex_t*>(blackbox));
142         pthread_mutexattr_t attr;
143
144         // Backtrack and get rid of the non-recursive mutex
145         pthread_mutex_destroy(mtx_ptr);
146
147         pthread_mutexattr_init(&attr);
148
149         pthread_mutexattr_settype(&attr,PTHREAD_MUTEX_RECURSIVE);
150
151         pthread_mutex_init(mtx_ptr,&attr);
152         pthread_mutexattr_destroy(&attr);
153 }
154
155
156
157 RWLock::RWLock()
158 {
159         pthread_rwlock_t*const rwlock_ptr(new pthread_rwlock_t);
160
161         pthread_rwlock_init(rwlock_ptr, NULL);
162
163         blackbox=rwlock_ptr;
164 }
165
166 RWLock::~RWLock()
167 {
168         pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
169
170         pthread_rwlock_destroy(rwlock_ptr);
171
172         delete rwlock_ptr;
173 }
174
175 void
176 RWLock::reader_lock()
177 {
178         pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
179
180         pthread_rwlock_rdlock(rwlock_ptr);
181 }
182
183 void
184 RWLock::reader_unlock()
185 {
186         pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
187
188         pthread_rwlock_unlock(rwlock_ptr);
189 }
190
191 bool
192 RWLock::reader_trylock()
193 {
194         pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
195
196         return !pthread_rwlock_tryrdlock(rwlock_ptr);
197 }
198
199 void
200 RWLock::writer_lock()
201 {
202         pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
203
204         pthread_rwlock_wrlock(rwlock_ptr);
205 }
206
207 void
208 RWLock::writer_unlock()
209 {
210         pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
211
212         pthread_rwlock_unlock(rwlock_ptr);
213 }
214
215 bool
216 RWLock::writer_trylock()
217 {
218         pthread_rwlock_t*const rwlock_ptr(static_cast<pthread_rwlock_t*>(blackbox));
219
220         return !pthread_rwlock_trywrlock(rwlock_ptr);
221 }
222
223 #endif
224
225 #ifdef USING_WIN32_THREADS
226 Mutex::Mutex()
227 {
228         HANDLE& mtx(*reinterpret_cast<HANDLE*>(&blackbox));
229         mtx=CreateMutex(NULL, FALSE, NULL);
230 }
231
232 Mutex::~Mutex()
233 {
234         HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
235         CloseHandle(mtx);
236 }
237
238 void
239 Mutex::lock()
240 {
241         HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
242         WaitForSingleObject(mtx, INFINITE);
243 }
244
245 void
246 Mutex::unlock()
247 {
248         HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
249         ReleaseMutex(mtx);
250 }
251
252 bool
253 Mutex::try_lock()
254 {
255         HANDLE mtx(reinterpret_cast<HANDLE>(blackbox));
256         return WaitForSingleObject(mtx, 0)==WAIT_FAILED;
257 }
258
259
260 RecMutex::RecMutex()
261 {
262         // Win32 mutexes are recursive by default.
263 }
264
265
266 RWLock::RWLock()
267 {
268 }
269
270 RWLock::~RWLock()
271 {
272 }
273
274 void
275 RWLock::reader_lock()
276 {
277 }
278
279 void
280 RWLock::reader_unlock()
281 {
282 }
283
284 bool
285 RWLock::reader_trylock()
286 {
287 }
288
289 void
290 RWLock::writer_lock()
291 {
292 }
293
294 void
295 RWLock::writer_unlock()
296 {
297 }
298
299 bool
300 RWLock::writer_trylock()
301 {
302 }
303
304 #endif