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