1 // Generated by gmmproc 2.64.2 -- DO NOT MODIFY!
2
3 //Stop the compiler warnings about using the deprecated API;
4 #define GLIB_DISABLE_DEPRECATION_WARNINGS 1
5
6 #include <glibmmconfig.h>
7 #ifndef GLIBMM_DISABLE_DEPRECATED
8
9
10 #include <glibmm.h>
11
12 #include <glibmm/thread.h>
13 #include <glibmm/private/thread_p.h>
14
15
16 /* Copyright (C) 2002 The gtkmm Development Team
17 *
18 * This library is free software; you can redistribute it and/or
19 * modify it under the terms of the GNU Lesser General Public
20 * License as published by the Free Software Foundation; either
21 * version 2.1 of the License, or (at your option) any later version.
22 *
23 * This library is distributed in the hope that it will be useful,
24 * but WITHOUT ANY WARRANTY; without even the implied warranty of
25 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
26 * Lesser General Public License for more details.
27 *
28 * You should have received a copy of the GNU Lesser General Public
29 * License along with this library. If not, see <http://www.gnu.org/licenses/>.
30 */
31
32 #include <glibmm/exceptionhandler.h>
33 #include <glib.h>
34
35 namespace
36 {
37
38 extern "C" {
39
40 static void*
call_thread_entry_slot(void * data)41 call_thread_entry_slot(void* data)
42 {
43 const auto slot = reinterpret_cast<sigc::slot_base*>(data);
44
45 try
46 {
47 // Recreate the specific slot, and drop the reference obtained by create().
48 (*static_cast<sigc::slot<void>*>(slot))();
49 }
50 catch (Glib::Thread::Exit&)
51 {
52 // Just exit from the thread. The Thread::Exit exception
53 // is our sane C++ replacement of g_thread_exit().
54 }
55 catch (...)
56 {
57 Glib::exception_handlers_invoke();
58 }
59
60 delete slot;
61 return nullptr;
62 }
63
64 } // extern "C"
65
66 } // anonymous namespace
67
68 namespace Glib
69 {
70
71 // This was always meant as an internal method. It is no longer called,
72 // and no longer needs to be called. We are keeping it just to avoid
73 // breaking ABI, though hopefully nobody is using it anyway.
74 // TODO: Remove this when we can break ABI.
75 void
thread_init_impl()76 thread_init_impl()
77 {
78 // Make sure the exception map is initialized before creating any thread.
79 Glib::Error::register_init();
80 }
81
82 /**** Glib::Thread *********************************************************/
83
84 // static
85 Thread*
create(const sigc::slot<void> & slot,bool)86 Thread::create(const sigc::slot<void>& slot, bool /* joinable */)
87 {
88 // Make a copy of slot on the heap
89 const auto slot_copy = new sigc::slot<void>(slot);
90
91 GError* error = nullptr;
92
93 const auto thread = g_thread_try_new(nullptr, &call_thread_entry_slot, slot_copy, &error);
94
95 if (error)
96 {
97 delete slot_copy;
98 // Glib::Error::throw_exception() will probably wrap G_THREAD_ERROR in a
99 // Glib::Threads::ThreadError instance, but we want a Glib::ThreadError.
100 if (error->domain == G_THREAD_ERROR)
101 throw Glib::ThreadError(error);
102 else
103 Glib::Error::throw_exception(error);
104 }
105
106 return reinterpret_cast<Thread*>(thread);
107 }
108
109 // static
110 Thread*
create(const sigc::slot<void> & slot,unsigned long stack_size,bool joinable,bool bound,ThreadPriority priority)111 Thread::create(const sigc::slot<void>& slot, unsigned long stack_size, bool joinable, bool bound,
112 ThreadPriority priority)
113 {
114 // Make a copy of slot on the heap
115 const auto slot_copy = new sigc::slot<void>(slot);
116
117 GError* error = nullptr;
118
119 const auto thread = g_thread_create_full(&call_thread_entry_slot, slot_copy, stack_size, joinable,
120 bound, (GThreadPriority)priority, &error);
121
122 if (error)
123 {
124 delete slot_copy;
125 // Glib::Error::throw_exception() will probably wrap G_THREAD_ERROR in a
126 // Glib::Threads::ThreadError instance, but we want a Glib::ThreadError.
127 if (error->domain == G_THREAD_ERROR)
128 throw Glib::ThreadError(error);
129 else
130 Glib::Error::throw_exception(error);
131 }
132
133 return reinterpret_cast<Thread*>(thread);
134 }
135
136 // static
137 Thread*
self()138 Thread::self()
139 {
140 return reinterpret_cast<Thread*>(g_thread_self());
141 }
142
143 void
join()144 Thread::join()
145 {
146 g_thread_join(&gobject_);
147 }
148
149 bool
joinable() const150 Thread::joinable() const
151 {
152 return true; // An appropriate result now that this is deprecated because all threads are now
153 // joinable.
154 }
155
156 void
set_priority(ThreadPriority priority)157 Thread::set_priority(ThreadPriority priority)
158 {
159 g_thread_set_priority(&gobject_, (GThreadPriority)priority);
160 }
161
162 ThreadPriority
get_priority() const163 Thread::get_priority() const
164 {
165 return THREAD_PRIORITY_NORMAL; // An appropriate result now that this is deprecated because the
166 // priority concept has been removed.
167 }
168
169 void
thread_init(GThreadFunctions *)170 thread_init(GThreadFunctions* /* vtable */)
171 {
172 // g_thread_init() is deprecated and now does nothing,
173 // so we do not even call it. That avoids a need to link to gthread-2.0,
174 // which contains the empty g_thread_init() implementation.
175 // g_thread_init(vtable);
176
177 Glib::thread_init_impl();
178 }
179
180 bool
thread_supported()181 thread_supported()
182 {
183 // MSVC++ needs the != 0 to avoid an int -> bool cast warning.
184 return (g_thread_supported() != 0);
185 }
186
187 // static
188 void
yield()189 Thread::yield()
190 {
191 g_thread_yield();
192 }
193
194 Thread*
wrap(GThread * gobject)195 wrap(GThread* gobject)
196 {
197 return reinterpret_cast<Thread*>(gobject);
198 }
199
200 /**** Glib::StaticMutex ****************************************************/
201
202 void
lock()203 StaticMutex::lock()
204 {
205 g_static_mutex_lock(&gobject_);
206 }
207
208 bool
trylock()209 StaticMutex::trylock()
210 {
211 return g_static_mutex_trylock(&gobject_);
212 }
213
214 void
unlock()215 StaticMutex::unlock()
216 {
217 g_static_mutex_unlock(&gobject_);
218 }
219
operator Mutex&()220 StaticMutex::operator Mutex&()
221 {
222 // If GStaticMutex is implemented as struct (e.g. on Linux), its first struct
223 // member (runtime_mutex) is a GMutex pointer. If the gthread implementation
224 // is native (i.e. the vtable pointer passed to g_thread_init() was 0), then
225 // the runtime_mutex pointer is unused, and the rest of the GStaticMutex
226 // struct resembles the mutex data.
227 //
228 // On Win32, GStaticMutex is just a typedef to struct _GMutex*. Either way,
229 // the first sizeof(GMutex*) bytes of GStaticMutex always resemble a GMutex
230 // pointer. The gthread implementation relies on that, and we'll also do so.
231
232 GMutex*& runtime_mutex = reinterpret_cast<GMutex*&>(gobject_);
233
234 // Fortunately, it cannot hurt if we set this to the GMutex pointer returned
235 // by g_static_mutex_get_mutex(). Either we just overwrite it with the same
236 // value, or it was unused anyway. Doing that allows casting the pointer
237 // location to a Glib::Mutex reference (its only data member is a GMutex*).
238
239 runtime_mutex = g_static_mutex_get_mutex(&gobject_);
240
241 return reinterpret_cast<Mutex&>(runtime_mutex);
242 }
243
244 /**** Glib::Mutex **********************************************************/
245
Mutex()246 Mutex::Mutex()
247 : gobject_(g_mutex_new()) // TODO: Use a statically-allocated GMutext instead, with g_mutex_init().
248 {
249 }
250
~Mutex()251 Mutex::~Mutex()
252 {
253 g_mutex_free(gobject_);
254 }
255
256 void
lock()257 Mutex::lock()
258 {
259 g_mutex_lock(gobject_);
260 }
261
262 bool
trylock()263 Mutex::trylock()
264 {
265 return g_mutex_trylock(gobject_);
266 }
267
268 void
unlock()269 Mutex::unlock()
270 {
271 g_mutex_unlock(gobject_);
272 }
273
274 /**** Glib::StaticRecMutex *************************************************/
275
276 void
lock()277 StaticRecMutex::lock()
278 {
279 g_static_rec_mutex_lock(&gobject_);
280 }
281
282 bool
trylock()283 StaticRecMutex::trylock()
284 {
285 return g_static_rec_mutex_trylock(&gobject_);
286 }
287
288 void
unlock()289 StaticRecMutex::unlock()
290 {
291 g_static_rec_mutex_unlock(&gobject_);
292 }
293
294 void
lock_full(unsigned int depth)295 StaticRecMutex::lock_full(unsigned int depth)
296 {
297 g_static_rec_mutex_lock_full(&gobject_, depth);
298 }
299
300 unsigned int
unlock_full()301 StaticRecMutex::unlock_full()
302 {
303 return g_static_rec_mutex_unlock_full(&gobject_);
304 }
305
operator RecMutex&()306 StaticRecMutex::operator RecMutex&()
307 {
308 return static_cast<RecMutex&>(*this);
309 }
310
311 /**** Glib::RecMutex *******************************************************/
312
RecMutex()313 RecMutex::RecMutex()
314 {
315 g_static_rec_mutex_init(&gobject_);
316 }
317
~RecMutex()318 RecMutex::~RecMutex()
319 {
320 g_static_rec_mutex_free(&gobject_);
321 }
322
323 /**** Glib::StaticRWLock ***************************************************/
324
325 void
reader_lock()326 StaticRWLock::reader_lock()
327 {
328 g_static_rw_lock_reader_lock(&gobject_);
329 }
330
331 bool
reader_trylock()332 StaticRWLock::reader_trylock()
333 {
334 return g_static_rw_lock_reader_trylock(&gobject_);
335 }
336
337 void
reader_unlock()338 StaticRWLock::reader_unlock()
339 {
340 g_static_rw_lock_reader_unlock(&gobject_);
341 }
342
343 void
writer_lock()344 StaticRWLock::writer_lock()
345 {
346 g_static_rw_lock_writer_lock(&gobject_);
347 }
348
349 bool
writer_trylock()350 StaticRWLock::writer_trylock()
351 {
352 return g_static_rw_lock_writer_trylock(&gobject_);
353 }
354
355 void
writer_unlock()356 StaticRWLock::writer_unlock()
357 {
358 g_static_rw_lock_writer_unlock(&gobject_);
359 }
360
operator RWLock&()361 StaticRWLock::operator RWLock&()
362 {
363 return static_cast<RWLock&>(*this);
364 }
365
366 /**** Glib::RWLock *********************************************************/
367
RWLock()368 RWLock::RWLock()
369 {
370 g_static_rw_lock_init(&gobject_);
371
372 // GLib doesn't have GRWLock, only GStaticRWLock. Force initialization
373 // of the mutex and the condition variables now, to mimic the behaviour
374 // of a (hypothetical) GRWLock.
375
376 if (g_static_mutex_get_mutex(&gobject_.mutex))
377 {
378 gobject_.read_cond = g_cond_new();
379 gobject_.write_cond = g_cond_new();
380 }
381 }
382
~RWLock()383 RWLock::~RWLock()
384 {
385 g_static_rw_lock_free(&gobject_);
386 }
387
388 /**** Glib::Cond ***********************************************************/
389
Cond()390 Cond::Cond() : gobject_(g_cond_new())
391 {
392 }
393
~Cond()394 Cond::~Cond()
395 {
396 g_cond_free(gobject_);
397 }
398
399 void
signal()400 Cond::signal()
401 {
402 g_cond_signal(gobject_);
403 }
404
405 void
broadcast()406 Cond::broadcast()
407 {
408 g_cond_broadcast(gobject_);
409 }
410
411 void
wait(Mutex & mutex)412 Cond::wait(Mutex& mutex)
413 {
414 g_cond_wait(gobject_, mutex.gobj());
415 }
416
417 bool
timed_wait(Mutex & mutex,const Glib::TimeVal & abs_time)418 Cond::timed_wait(Mutex& mutex, const Glib::TimeVal& abs_time)
419 {
420 return g_cond_timed_wait(gobject_, mutex.gobj(), const_cast<Glib::TimeVal*>(&abs_time));
421 }
422
423 void*
StaticPrivate_get_helper(GStaticPrivate * private_key)424 StaticPrivate_get_helper(GStaticPrivate* private_key)
425 {
426 return g_static_private_get(private_key);
427 }
428
429 void
StaticPrivate_set_helper(GStaticPrivate * private_key,gpointer data,GDestroyNotify notify)430 StaticPrivate_set_helper(GStaticPrivate* private_key, gpointer data, GDestroyNotify notify)
431 {
432 return g_static_private_set(private_key, data, notify);
433 }
434
435 GPrivate*
GPrivate_new_helper(GDestroyNotify notify)436 GPrivate_new_helper(GDestroyNotify notify)
437 {
438 return g_private_new(notify);
439 }
440
441 } // namespace Glib
442
443 namespace
444 {
445 } // anonymous namespace
446
447
ThreadError(Glib::ThreadError::Code error_code,const Glib::ustring & error_message)448 Glib::ThreadError::ThreadError(Glib::ThreadError::Code error_code, const Glib::ustring& error_message)
449 :
450 Glib::Error (G_THREAD_ERROR, error_code, error_message)
451 {}
452
ThreadError(GError * gobject)453 Glib::ThreadError::ThreadError(GError* gobject)
454 :
455 Glib::Error (gobject)
456 {}
457
code() const458 Glib::ThreadError::Code Glib::ThreadError::code() const
459 {
460 return static_cast<Code>(Glib::Error::code());
461 }
462
throw_func(GError * gobject)463 void Glib::ThreadError::throw_func(GError* gobject)
464 {
465 throw Glib::ThreadError(gobject);
466 }
467
468 #endif // GLIBMM_DISABLE_DEPRECATED
469
470
471