1 // Generated by gmmproc 2.64.2 -- DO NOT MODIFY!
2 #ifndef _GLIBMM_THREAD_H
3 #define _GLIBMM_THREAD_H
4 
5 #include <glibmmconfig.h>
6 
7 #ifndef GLIBMM_DISABLE_DEPRECATED
8 
9 
10 /* Copyright (C) 2002 The gtkmm Development Team
11  *
12  * This library is free software; you can redistribute it and/or
13  * modify it under the terms of the GNU Lesser General Public
14  * License as published by the Free Software Foundation; either
15  * version 2.1 of the License, or (at your option) any later version.
16  *
17  * This library is distributed in the hope that it will be useful,
18  * but WITHOUT ANY WARRANTY; without even the implied warranty of
19  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
20  * Lesser General Public License for more details.
21  *
22  * You should have received a copy of the GNU Lesser General Public
23  * License along with this library.  If not, see <http://www.gnu.org/licenses/>.
24  */
25 
26 
27  // This whole file is deprecated.
28 
29 
30 // We use GThreadFunctions in the (deprecated) API, so we must temporarily undef G_DISABLE_DEPRECATED.
31 // Temporarily undef G_DISABLE_DEPRECATED, redefining it later if appropriate.
32 // GLib ignores G_DISABLE_DEPRECATED since glib 2.61.2.
33 #if defined(G_DISABLE_DEPRECATED) && !defined(GLIBMM_G_DISABLE_DEPRECATED_UNDEFED)
34 //Stop the deprecation ifdef guards around the API declarations:
35 #undef G_DISABLE_DEPRECATED
36 #define GLIBMM_G_DISABLE_DEPRECATED_UNDEFED 1
37 #endif
38 
39 #include <glib.h>
40 
41 // Redefine G_DISABLE_DEPRECATED if it was defined before we temporarily undefed it:
42 #if defined(GLIBMM_G_DISABLE_DEPRECATED_UNDEFED)
43 #define G_DISABLE_DEPRECATED 1
44 #undef GLIBMM_G_DISABLE_DEPRECATED_UNDEFED
45 #endif
46 
47 
48 #include <glibmm/error.h>
49 #include <glibmm/timeval.h>
50 #include <sigc++/sigc++.h>
51 
52 #include <cstddef>
53 
54 // Necessary for glib 2.61.2 and newer.
55 G_GNUC_BEGIN_IGNORE_DEPRECATIONS
56 
57 /* Shadow THREAD_PRIORITY_NORMAL macro (from winbase.h).
58  */
59 #if defined(THREAD_PRIORITY_NORMAL) && !defined(GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL)
60 enum { GLIBMM_MACRO_DEFINITION_THREAD_PRIORITY_NORMAL = THREAD_PRIORITY_NORMAL };
61 #undef THREAD_PRIORITY_NORMAL
62 enum { THREAD_PRIORITY_NORMAL = GLIBMM_MACRO_DEFINITION_THREAD_PRIORITY_NORMAL };
63 #define THREAD_PRIORITY_NORMAL THREAD_PRIORITY_NORMAL
64 #define GLIBMM_MACRO_SHADOW_THREAD_PRIORITY_NORMAL 1
65 #endif
66 
67 
68 /** Initializer macro for Glib::StaticRecMutex.
69  * @relates Glib::StaticRecMutex
70  * @hideinitializer
71  *
72  * @deprecated Glib::StaticRecMutex is deprecated in favour of Glib::Threads::RecMutex, which can be used statically.
73  */
74 #define GLIBMM_STATIC_REC_MUTEX_INIT { G_STATIC_REC_MUTEX_INIT }
75 
76 /** Initializer macro for Glib::StaticRWLock.
77  * @relates Glib::StaticRWLock
78  * @hideinitializer
79  *
80  * @deprecated Glib::StaticRWLock is deprecated in favour of Glib::Threads::RWLock, which can be used statically.
81  */
82 #define GLIBMM_STATIC_RW_LOCK_INIT { G_STATIC_RW_LOCK_INIT }
83 
84 /** Initializer macro for Glib::StaticPrivate.
85  * @relates Glib::StaticPrivate
86  * @hideinitializer
87  *
88  * @deprecated Glib::StaticPrivate is deprecated in favour of Glib::Threads::Private, which can be used statically.
89  */
90 #define GLIBMM_STATIC_PRIVATE_INIT { G_STATIC_PRIVATE_INIT }
91 
92 namespace Glib
93 {
94 
95 /** @addtogroup glibmmEnums glibmm Enums and Flags */
96 
97 /**  @deprecated Thread priorities no longer have any effect.
98  *  @var ThreadPriority THREAD_PRIORITY_LOW
99  * A priority lower than normal.
100  *
101  *  @var ThreadPriority THREAD_PRIORITY_NORMAL
102  * The default priority.
103  *
104  *  @var ThreadPriority THREAD_PRIORITY_HIGH
105  * A priority higher than normal.
106  *
107  *  @var ThreadPriority THREAD_PRIORITY_URGENT
108  * The highest priority.
109  *
110  *  @enum ThreadPriority
111  *
112  * Thread priorities.
113  *
114  * Deprecated:2.32: Thread priorities no longer have any effect.
115  *
116  * @ingroup glibmmEnums
117  */
118 enum ThreadPriority
119 {
120   THREAD_PRIORITY_LOW,
121   THREAD_PRIORITY_NORMAL,
122   THREAD_PRIORITY_HIGH,
123   THREAD_PRIORITY_URGENT
124 };
125 
126 
127 /*! @var ThreadPriority THREAD_PRIORITY_LOW
128  * A priority lower than normal.
129  */
130 /*! @var ThreadPriority THREAD_PRIORITY_NORMAL
131  * The default priority.
132  */
133 /*! @var ThreadPriority THREAD_PRIORITY_HIGH
134  * A priority higher than normal.
135  */
136 /*! @var ThreadPriority THREAD_PRIORITY_URGENT
137  * The highest priority.
138  */
139 
140 /** Initializes the GLib thread system.
141  * @deprecated Calling thread_init() is no longer necessary and no longer has any effect.
142  */
143 void thread_init(GThreadFunctions* vtable = nullptr);
144 
145 /** Returns whether the thread system is initialized.
146  * @return @c true, if the thread system is initialized.
147  * @deprecated This is no longer useful, because the thread system is always initialized.
148  */
149 bool thread_supported();
150 
151 /**
152  * @deprecated Use Glib::Threads::NotLock instead.
153  */
154 enum NotLock { NOT_LOCK };
155 
156 /**
157  * @deprecated Use Glib::Threads::TryLock instead.
158  */
159 enum TryLock { TRY_LOCK };
160 
161 class GLIBMM_API Mutex;
162 class GLIBMM_API RecMutex;
163 class GLIBMM_API RWLock;
164 
165 struct GLIBMM_API StaticRecMutex;
166 struct GLIBMM_API StaticRWLock;
167 
168 
169 /**  %Exception class for thread-related errors.
170  * @deprecated Use Glib::Threads::ThreadError instead.
171  */
172 class GLIBMM_API ThreadError : public Glib::Error
173 {
174 public:
175   /**  @var Code AGAIN
176    * A thread couldn't be created due to resource
177    * shortage. Try again later.
178    *
179    *  @enum Code
180    *
181    * Possible errors of thread related functions.
182    */
183   enum Code
184   {
185     AGAIN
186   };
187 
188   ThreadError(Code error_code, const Glib::ustring& error_message);
189   explicit ThreadError(GError* gobject);
190   Code code() const;
191 
192 #ifndef DOXYGEN_SHOULD_SKIP_THIS
193 private:
194 
195   static void throw_func(GError* gobject);
196 
197   friend GLIBMM_API void wrap_init(); // uses throw_func()
198 
199   #endif //DOXYGEN_SHOULD_SKIP_THIS
200 };
201 
202 
203 /** Represents a running thread.
204  * An instance of this class can only be obtained with create(), self(),
205  * or wrap(GThread*).  It's not possible to delete a Thread object.  If the
206  * thread is @em not joinable, its resources will be freed automatically
207  * when it exits.  Otherwise, if the thread @em is joinable, you must call
208  * join() to avoid a memory leak.
209  *
210  * @note g_thread_exit() is not wrapped, because that function exits a thread
211  * without any cleanup.  That's especially dangerous in C++ code, since the
212  * destructors of automatic objects won't be invoked.  Instead, you can throw
213  * a Thread::Exit exception, which will be caught by the internal thread
214  * entry function.
215  *
216  * @note You might have noticed that the thread entry slot doesn't have the
217  * usual void* return value.  If you want to return any data from your thread
218  * you can pass an additional output argument to the thread's entry slot.
219  *
220  * @deprecated Use Glib::Threads::Thread instead.
221  */
222 class GLIBMM_API Thread
223 {
224 public:
225 
226   Thread(const Thread&) = delete;
227   Thread& operator=(const Thread&) = delete;
228 
229   class Exit;
230 
231   //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
232   /** Creates a new thread with the priority <tt>THREAD_PRIORITY_NORMAL</tt>.
233    * If @a joinable is @c true, you can wait for this thread's termination by
234    * calling join().  Otherwise the thread will just disappear, when ready.
235    *
236    * The new thread executes the function or method @a slot points to.  You can
237    * pass additional arguments using sigc::bind().  If the thread was created
238    * successfully, it is returned, otherwise a ThreadError exception is thrown.
239    *
240    * Because sigc::trackable is not thread safe, if the slot represents a
241    * non-static class method (that is, it is created by sigc::mem_fun()), the
242    * class concerned should not derive from sigc::trackable.
243    *
244    * @param slot A slot to execute in the new thread.
245    * @param joinable This parameter is now ignored because Threads are now always joinable.
246    * @return The new Thread* on success.
247    * @throw Glib::ThreadError
248    */
249   static Thread* create(const sigc::slot<void>& slot, bool joinable = true);
250 
251   /** Returns the Thread* corresponding to the calling thread.
252    * @return The current thread.
253    */
254   static Thread* self();
255 
256   /** Waits until the thread finishes.
257    * Waits until the thread finishes, i.e. the slot, as given to create(),
258    * returns or g_thread_exit() is called by the thread.  (Calling
259    * g_thread_exit() in a C++ program should be avoided.)  All resources of
260    * the thread including the Glib::Thread object are released.  The thread
261    * must have been created with <tt>joinable&nbsp;=&nbsp;true</tt>.
262    */
263   void join();
264 
265   //See http://bugzilla.gnome.org/show_bug.cgi?id=512348 about the sigc::trackable issue.
266   /** Creates a new thread with the priority @a priority. The stack gets the
267    * size @a stack_size or the default value for the current platform, if
268    * @a stack_size is <tt>0</tt>.
269    *
270    * If @a joinable is @c true, you can wait for this thread's termination by
271    * calling join().  Otherwise the thread will just disappear, when ready.
272    * If @a bound is @c true, this thread will be scheduled in the system scope,
273    * otherwise the implementation is free to do scheduling in the process
274    * scope.  The first variant is more expensive resource-wise, but generally
275    * faster.  On some systems (e.g. Linux) all threads are bound.
276    *
277    * The new thread executes the function or method @a slot points to.  You can
278    * pass additional arguments using sigc::bind().  If the thread was created
279    * successfully, it is returned.
280    *
281    * Because sigc::trackable is not thread safe, if the slot represents a
282    * non-static class method (that is, it is created by sigc::mem_fun()), the
283    * class concerned should not derive from sigc::trackable.
284    *
285    * @note It is not guaranteed, that threads with different priorities really
286    * behave accordingly.  On some systems (e.g. Linux) only root can increase
287    * priorities.  On other systems (e.g. Solaris) there doesn't seem to be
288    * different scheduling for different priorities.  All in all try to avoid
289    * being dependent on priorities.  Use <tt>Glib::THREAD_PRIORITY_NORMAL</tt>
290    * here as a default.
291    *
292    * @note Only use the extended
293    * create(const sigc::slot<void>&, unsigned long, bool, bool, ThreadPriority)
294    * function, when you really can't use the simple
295    * create(const sigc::slot<void>&, bool)
296    * instead.  The latter overload does not take @a stack_size, @a bound and
297    * @a priority as arguments, as they should only be used for cases, where
298    * it is inevitable.
299    *
300    * @param slot A slot to execute in the new thread.
301    * @param stack_size A stack size for the new thread, or <tt>0</tt>.
302    * @param joinable Should this thread be joinable?
303    * @param bound Should this thread be bound to a system thread?
304    * @param priority A priority for the thread.
305    * @return The new Thread* on success.
306    * @throw Glib::ThreadError
307    *
308    * @deprecated Use the simpler create() method instead, because all Threads
309    * are now joinable, and bounds and priority parameters now have no effect.
310    */
311   static Thread* create(const sigc::slot<void>& slot, unsigned long stack_size,
312                         bool joinable, bool bound, ThreadPriority priority);
313 
314   /** Returns whether the thread is joinable.
315    * @return Whether the thread is joinable.
316    *
317    * @deprecated All threads are now joinable.
318    */
319   bool joinable() const;
320 
321   /** Changes the priority of the thread to @a priority.
322    * @note It is not guaranteed, that threads with different priorities really
323    * behave accordingly.  On some systems (e.g. Linux) only @c root can
324    * increase priorities.  On other systems (e.g. Solaris) there doesn't seem
325    * to be different scheduling for different priorities.  All in all try to
326    * avoid being dependent on priorities.
327    * @param priority A new priority for the thread.
328    *
329    * @deprecated Thread priorities no longer have any effect.
330    */
331   void set_priority(ThreadPriority priority);
332 
333   /** Returns the priority of the thread.
334    * @return The thread's priority.
335    *
336    * @deprecated Thread priorities no longer have any effect.
337    */
338   ThreadPriority get_priority() const;
339 
340   /** Gives way to other threads waiting to be scheduled.
341    * This function is often used as a method to make busy wait less evil.  But
342    * in most cases, you will encounter, there are better methods to do that.
343    * So in general you shouldn't use this function.
344    */
345   static void yield();
346 
gobj()347   GThread*       gobj()       { return &gobject_; }
gobj()348   const GThread* gobj() const { return &gobject_; }
349 
350 private:
351   GThread gobject_;
352 
353   // Glib::Thread can neither be constructed nor deleted.
354   Thread();
355   void operator delete(void*, std::size_t);
356 };
357 
358 /** %Exception class used to exit from a thread.
359  * @code
360  * throw Glib::Thread::Exit();
361  * @endcode
362  * Write this if you want to exit from a thread created by Thread::create().
363  * Of course you must make sure not to catch Thread::Exit by accident, i.e.
364  * when using <tt>catch(...)</tt> somewhere in your code.
365  *
366  * @deprecated Use Glib::Threads::Thread::Exit instead.
367  */
368 class GLIBMM_API Thread::Exit
369 {};
370 
371 
372 //TODO: Make sure that Glib::wrap() uses Glib::Threads::wrap() instead.
373 
374 /** @relates Glib::Thread
375  *
376  * @deprecated Use Glib::Threads::wrap(GThread*) instead.
377  */
378 Thread* wrap(GThread* gobject);
379 
380 struct StaticMutex;
381 
382 /** Like Glib::Mutex, but can be defined at compile time.
383  * Use @c GLIBMM_STATIC_MUTEX_INIT to initialize a StaticMutex:
384  * @code
385  * Glib::StaticMutex mutex = GLIBMM_STATIC_MUTEX_INIT;
386  * @endcode
387  *
388  * A StaticMutex can be used without calling Glib::thread_init(), it will
389  * silently do nothing then.  That will also work when using the implicit
390  * conversion to Mutex&, thus you can safely use Mutex::Lock with a
391  * StaticMutex.
392  *
393  * @deprecated Use Glib::Threads::Mutex instead, which can be used statically.
394  */
395 struct StaticMutex
396 {
397   void lock();
398   bool trylock();
399   void unlock();
400 
401   operator Mutex&();
402 
gobjStaticMutex403   GStaticMutex* gobj() { return &gobject_; }
404 
405 #ifndef DOXYGEN_SHOULD_SKIP_THIS
406   // Must be public to allow initialization at compile time.
407   GStaticMutex gobject_;
408 #endif
409 };
410 
411 /** Initializer macro for Glib::StaticMutex.
412  * @relates Glib::StaticMutex
413  * @hideinitializer
414  *
415  * @deprecated  Glib::StaticMutex is deprecated in favour of Glib::Threads::Mutex, which can be used statically.
416  */
417 #define GLIBMM_STATIC_MUTEX_INIT { G_STATIC_MUTEX_INIT }
418 
419 /** Represents a mutex (mutual exclusion).
420  * It can be used to protect data against shared access.  Try to use
421  * Mutex::Lock instead of calling lock() and unlock() directly&nbsp;--
422  * it will make your life much easier.
423  *
424  * @note Glib::Mutex is not recursive, i.e. a thread will deadlock, if it
425  * already has locked the mutex while calling lock().  Use Glib::RecMutex
426  * instead, if you need recursive mutexes.
427  *
428  * @deprecated Use Glib::Threads::Mutex instead.
429  */
430 class GLIBMM_API Mutex
431 {
432 public:
433   class Lock;
434 
435   Mutex();
436 
437   Mutex(const Mutex&) = delete;
438   Mutex& operator=(const Mutex&) = delete;
439 
440   ~Mutex();
441 
442   /** Locks the mutex.
443    * If mutex is already locked by another thread, the current thread will
444    * block until mutex is unlocked by the other thread.
445    * @see Mutex::Lock
446    */
447   void lock();
448 
449   /** Tries to lock the mutex.
450    * If the mutex is already locked by another thread, it immediately returns
451    * @c false.  Otherwise it locks the mutex and returns @c true.
452    * @return Whether the mutex could be locked.
453    * @see Mutex::Lock
454    */
455   bool trylock();
456 
457   /** Unlocks the mutex.
458    * If another thread is blocked in a lock() call for this mutex, it will be
459    * woken and can lock the mutex itself.
460    * @see Mutex::Lock
461    */
462   void unlock();
463 
gobj()464   GMutex* gobj() { return gobject_; }
465 
466 private:
467   GMutex* gobject_;
468 };
469 
470 /** Utility class for exception-safe mutex locking.
471  * @par Usage example:
472  * @code
473  * {
474  *   Glib::Mutex::Lock lock (mutex); // calls mutex.lock()
475  *   do_something();
476  * } // the destructor calls mutex.unlock()
477  * @endcode
478  * As you can see, the compiler takes care of the unlocking.  This is not
479  * only exception safe but also much less error-prone.  You could even
480  * <tt>return</tt> while still holding the lock and it will be released
481  * properly.
482  *
483  * @deprecated Use Glib::Threads::Mutex::Lock instead.
484  */
485 class GLIBMM_API Mutex::Lock
486 {
487 public:
488   explicit inline Lock(Mutex& mutex);
489   inline Lock(Mutex& mutex, NotLock);
490   inline Lock(Mutex& mutex, TryLock);
491   inline ~Lock();
492 
493   inline void acquire();
494   inline bool try_acquire();
495   inline void release();
496   inline bool locked() const;
497 
498 private:
499   Mutex&  mutex_;
500   bool    locked_;
501 
502 
503 };
504 
505 
506 /** Like Glib::RecMutex, but can be defined at compile time.
507  * Use @c GLIBMM_STATIC_REC_MUTEX_INIT to initialize a StaticRecMutex:
508  * @code
509  * Glib::StaticRecMutex mutex = GLIBMM_STATIC_REC_MUTEX_INIT;
510  * @endcode
511  * A StaticRecMutex can be used without calling Glib::thread_init(), it will
512  * silently do nothing then.  That will also work when using the implicit
513  * conversion to RecMutex&, thus you can safely use RecMutex::Lock with a
514  * StaticRecMutex.
515  *
516  * @deprecated Use Glib::Threads::RecMutex instead, which can be used statically.
517  */
518 struct StaticRecMutex
519 {
520   void lock();
521   bool trylock();
522   void unlock();
523 
524   void lock_full(unsigned int depth);
525   unsigned int unlock_full();
526 
527   operator RecMutex&();
528 
gobjStaticRecMutex529   GStaticRecMutex* gobj() { return &gobject_; }
530 
531 #ifndef DOXYGEN_SHOULD_SKIP_THIS
532   // Must be public to allow initialization at compile time.
533   GStaticRecMutex gobject_;
534 #endif
535 };
536 
537 /**
538  *
539  * @deprecated Use Glib::Threads::RecMutex instead.
540  */
541 class GLIBMM_API RecMutex : public StaticRecMutex
542 {
543 public:
544   class Lock;
545 
546   RecMutex();
547   ~RecMutex();
548 
549 private:
550   // noncopyable
551   RecMutex(const RecMutex&);
552   RecMutex& operator=(const RecMutex&);
553 };
554 
555 /** Utility class for exception-safe locking of recursive mutexes.
556  *
557  * @deprecated Use Glib::Threads::RecMutex instead.
558  */
559 class GLIBMM_API RecMutex::Lock
560 {
561 public:
562   explicit inline Lock(RecMutex& mutex);
563   inline Lock(RecMutex& mutex, NotLock);
564   inline Lock(RecMutex& mutex, TryLock);
565 
566   Lock(const RecMutex::Lock&) = delete;
567   RecMutex::Lock& operator=(const RecMutex::Lock&) = delete;
568 
569   inline ~Lock();
570 
571   inline void acquire();
572   inline bool try_acquire();
573   inline void release();
574   inline bool locked() const;
575 
576 private:
577   RecMutex& mutex_;
578   bool      locked_;
579 };
580 
581 
582 /** Like Glib::RWLock, but can be defined at compile time.
583  * Use @c GLIBMM_STATIC_RW_LOCK_INIT to initialize a StaticRWLock:
584  * @code
585  * Glib::StaticRWLock rw_lock = GLIBMM_STATIC_RW_LOCK_INIT;
586  * @endcode
587  * A StaticRWLock can be used without calling Glib::thread_init(), it will
588  * silently do nothing then.  That will also work when using the implicit
589  * conversion to RWLock&, thus you can safely use RWLock::ReaderLock and
590  * RWLock::WriterLock with a StaticRWLock.
591  *
592  * @deprecated Use Glib::Threads::RWLock instead, which can be used statically.
593  */
594 struct StaticRWLock
595 {
596   void reader_lock();
597   bool reader_trylock();
598   void reader_unlock();
599 
600   void writer_lock();
601   bool writer_trylock();
602   void writer_unlock();
603 
604   operator RWLock&();
605 
gobjStaticRWLock606   GStaticRWLock* gobj() { return &gobject_; }
607 
608 #ifndef DOXYGEN_SHOULD_SKIP_THIS
609   // Must be public to allow initialization at compile time.
610   GStaticRWLock gobject_;
611 #endif
612 };
613 
614 /**
615  *
616  * @deprecated Use Glib::Threads::RWLock instead.
617  */
618 class GLIBMM_API RWLock : public StaticRWLock
619 {
620 public:
621   class ReaderLock;
622   class WriterLock;
623 
624   RWLock();
625 
626   RWLock(const RWLock&) = delete;
627   RWLock& operator=(const RWLock&) = delete;
628 
629   ~RWLock();
630 };
631 
632 /** Utility class for exception-safe locking of read/write locks.
633  *
634  * @deprecated Use Glib::Threads::RWLock::ReaderLock instead.
635  */
636 class GLIBMM_API RWLock::ReaderLock
637 {
638 public:
639   explicit inline ReaderLock(RWLock& rwlock);
640   inline ReaderLock(RWLock& rwlock, NotLock);
641   inline ReaderLock(RWLock& rwlock, TryLock);
642 
643   ReaderLock(const RWLock::ReaderLock&) = delete;
644   RWLock::ReaderLock& operator=(const RWLock::ReaderLock&) = delete;
645 
646   inline ~ReaderLock();
647 
648   inline void acquire();
649   inline bool try_acquire();
650   inline void release();
651   inline bool locked() const;
652 
653 private:
654   RWLock& rwlock_;
655   bool    locked_;
656 };
657 
658 /** Utility class for exception-safe locking of read/write locks.
659  *
660  * @deprecated Use Glib::Threads::RWLock::WriterLock instead.
661  */
662 class GLIBMM_API RWLock::WriterLock
663 {
664 public:
665   explicit inline WriterLock(RWLock& rwlock);
666   inline WriterLock(RWLock& rwlock, NotLock);
667   inline WriterLock(RWLock& rwlock, TryLock);
668 
669   WriterLock(const RWLock::WriterLock&) = delete;
670   RWLock::WriterLock& operator=(const RWLock::WriterLock&) = delete;
671 
672   inline ~WriterLock();
673 
674   inline void acquire();
675   inline bool try_acquire();
676   inline void release();
677   inline bool locked() const;
678 
679 private:
680   RWLock& rwlock_;
681   bool    locked_;
682 };
683 
684 /** An opaque data structure to represent a condition.
685  * A @a Cond is an object that threads can block on, if they find a certain
686  * condition to be false. If other threads change the state of this condition
687  * they can signal the @a Cond, such that the waiting thread is woken up.
688  * @par Usage example:
689  * @code
690  * Glib::Cond  data_cond;
691  * Glib::Mutex data_mutex;
692  * void* current_data = nullptr;
693  *
694  * void push_data(void* data)
695  * {
696  *   Glib::Mutex::Lock lock (data_mutex);
697  *
698  *   current_data = data;
699  *   data_cond.signal();
700  * }
701  *
702  * void* pop_data()
703  * {
704  *   Glib::Mutex::Lock lock (data_mutex);
705  *
706  *   while (!current_data)
707  *     data_cond.wait(data_mutex);
708  *
709  *   void *const data = current_data;
710  *   current_data = nullptr;
711  *
712  *   return data;
713  * }
714  * @endcode
715  *
716  * @deprecated Use Glib::Threads::Cond instead.
717  */
718 class GLIBMM_API Cond
719 {
720 public:
721   Cond();
722 
723   Cond(const Cond&) = delete;
724   Cond& operator=(const Cond&) = delete;
725 
726   ~Cond();
727 
728   /** If threads are waiting for this @a Cond, exactly one of them is woken up.
729    * It is good practice to hold the same lock as the waiting thread, while calling
730    * this method, though not required.
731    *
732    */
733   void signal();
734 
735   /** If threads are waiting for this @a Cond, all of them are woken up.
736    * It is good practice to hold the same lock as the waiting thread, while calling
737    * this method, though not required.
738    */
739   void broadcast();
740 
741   /** Waits until this thread is woken up on this @a Cond.
742    * The mutex is unlocked before falling asleep and locked again before resuming.
743    *
744    * @param mutex a @a Mutex that is currently locked.
745    *
746    * @note It is important to use the @a wait() and @a timed_wait() methods
747    * only inside a loop, which checks for the condition to be true as it is not
748    * guaranteed that the waiting thread will find it fulfilled, even if the signaling
749    * thread left the condition in that state. This is because another thread can have
750    * altered the condition, before the waiting thread got the chance to be woken up,
751    * even if the condition itself is protected by a @a Mutex.
752    */
753   void wait(Mutex& mutex);
754 
755   /** Waits until this thread is woken up on this @a Cond, but not longer than until the time, that is specified by @a abs_time.
756    * The mutex is unlocked before falling asleep and locked again before resuming.
757    *
758    * @param mutex a @a Mutex that is currently locked.
759    * @param abs_time a max time to wait.
760    *
761    * @note It is important to use the @a wait() and @a timed_wait() methods
762    * only inside a loop, which checks for the condition to be true as it is not
763    * guaranteed that the waiting thread will find it fulfilled, even if the signaling
764    * thread left the condition in that state. This is because another thread can have
765    * altered the condition, before the waiting thread got the chance to be woken up,
766    * even if the condition itself is protected by a @a Mutex.
767    */
768   bool timed_wait(Mutex& mutex, const Glib::TimeVal& abs_time);
769 
gobj()770   GCond* gobj() { return gobject_; }
771 
772 private:
773   GCond* gobject_;
774 };
775 
776 
777 /** Thread-local data pointer.
778  *
779  * @deprecated Use Glib::Threads::Private instead, which can be used statically.
780  */
781 template <class T>
782 struct StaticPrivate
783 {
784   using DestroyNotifyFunc =  void (*) (void*);
785 
786   static void delete_ptr(void* data);
787 
788   inline T* get();
789   inline void set(T* data, DestroyNotifyFunc notify_func = &StaticPrivate<T>::delete_ptr);
790 
gobjStaticPrivate791   GStaticPrivate* gobj() { return &gobject_; }
792 
793 #ifndef DOXYGEN_SHOULD_SKIP_THIS
794   // Must be public to allow initialization at compile time.
795   GStaticPrivate gobject_;
796 #endif
797 };
798 
799 /** Thread-local data pointer.
800  *
801  * @deprecated Use Glib::Threads::Private instead.
802  */
803 template <class T>
804 class Private
805 {
806 public:
807 
808   Private(const Private<T>&) = delete;
809   Private<T>& operator=(const Private<T>&) = delete;
810 
811   using DestructorFunc = void (*) (void*);
812 
813   static void delete_ptr(void* data);
814 
815   explicit inline Private(DestructorFunc destructor_func = &Private<T>::delete_ptr);
816   inline T* get();
817   inline void set(T* data);
818 
gobj()819   GPrivate* gobj() { return gobject_; }
820 
821 private:
822   GPrivate* gobject_;
823 };
824 
825 /** @} group Threads */
826 
827 /*! A glibmm thread example.
828  * @example thread/thread.cc
829  */
830 
831 
832 #ifndef DOXYGEN_SHOULD_SKIP_THIS
833 
834 /***************************************************************************/
835 /*  inline implementation                                                  */
836 /***************************************************************************/
837 
838 // internal
839 /** @deprecated This was always for internal glibmm use and is now unecessary even inside glibmm.
840  */
841 void thread_init_impl();
842 
843 /**** Glib::Mutex::Lock ****************************************************/
844 
845 inline
Lock(Mutex & mutex)846 Mutex::Lock::Lock(Mutex& mutex)
847 :
848   mutex_  (mutex),
849   locked_ (true)
850 {
851   mutex_.lock();
852 }
853 
854 inline
Lock(Mutex & mutex,NotLock)855 Mutex::Lock::Lock(Mutex& mutex, NotLock)
856 :
857   mutex_  (mutex),
858   locked_ (false)
859 {}
860 
861 inline
Lock(Mutex & mutex,TryLock)862 Mutex::Lock::Lock(Mutex& mutex, TryLock)
863 :
864   mutex_  (mutex),
865   locked_ (mutex.trylock())
866 {}
867 
868 inline
~Lock()869 Mutex::Lock::~Lock()
870 {
871   if(locked_)
872     mutex_.unlock();
873 }
874 
875 inline
acquire()876 void Mutex::Lock::acquire()
877 {
878   mutex_.lock();
879   locked_ = true;
880 }
881 
882 inline
try_acquire()883 bool Mutex::Lock::try_acquire()
884 {
885   locked_ = mutex_.trylock();
886   return locked_;
887 }
888 
889 inline
release()890 void Mutex::Lock::release()
891 {
892   mutex_.unlock();
893   locked_ = false;
894 }
895 
896 inline
locked()897 bool Mutex::Lock::locked() const
898 {
899   return locked_;
900 }
901 
902 
903 /**** Glib::RecMutex::Lock *************************************************/
904 
905 inline
Lock(RecMutex & mutex)906 RecMutex::Lock::Lock(RecMutex& mutex)
907 :
908   mutex_  (mutex),
909   locked_ (true)
910 {
911   mutex_.lock();
912 }
913 
914 inline
Lock(RecMutex & mutex,NotLock)915 RecMutex::Lock::Lock(RecMutex& mutex, NotLock)
916 :
917   mutex_  (mutex),
918   locked_ (false)
919 {}
920 
921 inline
Lock(RecMutex & mutex,TryLock)922 RecMutex::Lock::Lock(RecMutex& mutex, TryLock)
923 :
924   mutex_  (mutex),
925   locked_ (mutex.trylock())
926 {}
927 
928 inline
~Lock()929 RecMutex::Lock::~Lock()
930 {
931   if(locked_)
932     mutex_.unlock();
933 }
934 
935 inline
acquire()936 void RecMutex::Lock::acquire()
937 {
938   mutex_.lock();
939   locked_ = true;
940 }
941 
942 inline
try_acquire()943 bool RecMutex::Lock::try_acquire()
944 {
945   locked_ = mutex_.trylock();
946   return locked_;
947 }
948 
949 inline
release()950 void RecMutex::Lock::release()
951 {
952   mutex_.unlock();
953   locked_ = false;
954 }
955 
956 inline
locked()957 bool RecMutex::Lock::locked() const
958 {
959   return locked_;
960 }
961 
962 
963 /**** Glib::RWLock::ReaderLock *********************************************/
964 
965 inline
ReaderLock(RWLock & rwlock)966 RWLock::ReaderLock::ReaderLock(RWLock& rwlock)
967 :
968   rwlock_ (rwlock),
969   locked_ (true)
970 {
971   rwlock_.reader_lock();
972 }
973 
974 inline
ReaderLock(RWLock & rwlock,NotLock)975 RWLock::ReaderLock::ReaderLock(RWLock& rwlock, NotLock)
976 :
977   rwlock_ (rwlock),
978   locked_ (false)
979 {}
980 
981 inline
ReaderLock(RWLock & rwlock,TryLock)982 RWLock::ReaderLock::ReaderLock(RWLock& rwlock, TryLock)
983 :
984   rwlock_ (rwlock),
985   locked_ (rwlock.reader_trylock())
986 {}
987 
988 inline
~ReaderLock()989 RWLock::ReaderLock::~ReaderLock()
990 {
991   if(locked_)
992     rwlock_.reader_unlock();
993 }
994 
995 inline
acquire()996 void RWLock::ReaderLock::acquire()
997 {
998   rwlock_.reader_lock();
999   locked_ = true;
1000 }
1001 
1002 inline
try_acquire()1003 bool RWLock::ReaderLock::try_acquire()
1004 {
1005   locked_ = rwlock_.reader_trylock();
1006   return locked_;
1007 }
1008 
1009 inline
release()1010 void RWLock::ReaderLock::release()
1011 {
1012   rwlock_.reader_unlock();
1013   locked_ = false;
1014 }
1015 
1016 inline
locked()1017 bool RWLock::ReaderLock::locked() const
1018 {
1019   return locked_;
1020 }
1021 
1022 
1023 /**** Glib::RWLock::WriterLock *********************************************/
1024 
1025 inline
WriterLock(RWLock & rwlock)1026 RWLock::WriterLock::WriterLock(RWLock& rwlock)
1027 :
1028   rwlock_ (rwlock),
1029   locked_ (true)
1030 {
1031   rwlock_.writer_lock();
1032 }
1033 
1034 inline
WriterLock(RWLock & rwlock,NotLock)1035 RWLock::WriterLock::WriterLock(RWLock& rwlock, NotLock)
1036 :
1037   rwlock_ (rwlock),
1038   locked_ (false)
1039 {}
1040 
1041 inline
WriterLock(RWLock & rwlock,TryLock)1042 RWLock::WriterLock::WriterLock(RWLock& rwlock, TryLock)
1043 :
1044   rwlock_ (rwlock),
1045   locked_ (rwlock.writer_trylock())
1046 {}
1047 
1048 inline
~WriterLock()1049 RWLock::WriterLock::~WriterLock()
1050 {
1051   if(locked_)
1052     rwlock_.writer_unlock();
1053 }
1054 
1055 inline
acquire()1056 void RWLock::WriterLock::acquire()
1057 {
1058   rwlock_.writer_lock();
1059   locked_ = true;
1060 }
1061 
1062 inline
try_acquire()1063 bool RWLock::WriterLock::try_acquire()
1064 {
1065   locked_ = rwlock_.writer_trylock();
1066   return locked_;
1067 }
1068 
1069 inline
release()1070 void RWLock::WriterLock::release()
1071 {
1072   rwlock_.writer_unlock();
1073   locked_ = false;
1074 }
1075 
1076 inline
locked()1077 bool RWLock::WriterLock::locked() const
1078 {
1079   return locked_;
1080 }
1081 
1082 
1083 /**** Glib::StaticPrivate **************************************************/
1084 
1085 // static
1086 template <class T>
delete_ptr(void * data)1087 void StaticPrivate<T>::delete_ptr(void* data)
1088 {
1089   delete static_cast<T*>(data);
1090 }
1091 
1092 /** This is only for use by glibmm itself.
1093  */
1094 void* StaticPrivate_get_helper(GStaticPrivate *private_key);
1095 
1096 template <class T> inline
get()1097 T* StaticPrivate<T>::get()
1098 {
1099   return static_cast<T*>(StaticPrivate_get_helper(&gobject_));
1100 }
1101 
1102 /** This is only for use by glibmm itself.
1103  */
1104 void StaticPrivate_set_helper(GStaticPrivate *private_key, gpointer data, GDestroyNotify notify);
1105 
1106 template <class T> inline
set(T * data,typename StaticPrivate<T>::DestroyNotifyFunc notify_func)1107 void StaticPrivate<T>::set(T* data, typename StaticPrivate<T>::DestroyNotifyFunc notify_func)
1108 {
1109   StaticPrivate_set_helper(&gobject_, data, notify_func);
1110 }
1111 
1112 
1113 /**** Glib::Private ********************************************************/
1114 
1115 // static
1116 template <class T>
delete_ptr(void * data)1117 void Private<T>::delete_ptr(void* data)
1118 {
1119   delete static_cast<T*>(data);
1120 }
1121 
1122 /** This is only for use by glibmm itself.
1123  */
1124 GPrivate* GPrivate_new_helper(GDestroyNotify notify);
1125 
1126 template <class T> inline
Private(typename Private<T>::DestructorFunc destructor_func)1127 Private<T>::Private(typename Private<T>::DestructorFunc destructor_func)
1128 :
1129   gobject_ (GPrivate_new_helper(destructor_func))
1130 {}
1131 
1132 template <class T> inline
get()1133 T* Private<T>::get()
1134 {
1135   return static_cast<T*>(g_private_get(gobject_));
1136 }
1137 
1138 template <class T> inline
set(T * data)1139 void Private<T>::set(T* data)
1140 {
1141   g_private_set(gobject_, data);
1142 }
1143 
1144 #endif /* DOXYGEN_SHOULD_SKIP_THIS */
1145 
1146 } // namespace Glib
1147 
1148 G_GNUC_END_IGNORE_DEPRECATIONS
1149 
1150 
1151 #endif // GLIBMM_DISABLE_DEPRECATED
1152 
1153 
1154 #endif /* _GLIBMM_THREAD_H */
1155 
1156