c++-gtk-utils
mutex.h
Go to the documentation of this file.
1 /* Copyright (C) 2005 to 2014 Chris Vine
2 
3 The library comprised in this file or of which this file is part is
4 distributed by Chris Vine under the GNU Lesser General Public
5 License as follows:
6 
7  This library is free software; you can redistribute it and/or
8  modify it under the terms of the GNU Lesser General Public License
9  as published by the Free Software Foundation; either version 2.1 of
10  the License, or (at your option) any later version.
11 
12  This library is distributed in the hope that it will be useful, but
13  WITHOUT ANY WARRANTY; without even the implied warranty of
14  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
15  Lesser General Public License, version 2.1, for more details.
16 
17  You should have received a copy of the GNU Lesser General Public
18  License, version 2.1, along with this library (see the file LGPL.TXT
19  which came with this source code package in the c++-gtk-utils
20  sub-directory); if not, write to the Free Software Foundation, Inc.,
21  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 
23 However, it is not intended that the object code of a program whose
24 source code instantiates a template from this file or uses macros or
25 inline functions (of any length) should by reason only of that
26 instantiation or use be subject to the restrictions of use in the GNU
27 Lesser General Public License. With that in mind, the words "and
28 macros, inline functions and instantiations of templates (of any
29 length)" shall be treated as substituted for the words "and small
30 macros and small inline functions (ten lines or less in length)" in
31 the fourth paragraph of section 5 of that licence. This does not
32 affect any other reason why object code may be subject to the
33 restrictions in that licence (nor for the avoidance of doubt does it
34 affect the application of section 2 of that licence to modifications
35 of the source code in this file).
36 
37 */
38 
39 #ifndef CGU_MUTEX_H
40 #define CGU_MUTEX_H
41 
42 #include <exception>
43 #include <pthread.h>
44 #include <time.h>
45 
46 #include <glib.h>
48 
49 /**
50  * @file mutex.h
51  * @brief Provides wrapper classes for pthread mutexes and condition
52  * variables, and scoped locking classes for exception safe mutex
53  * locking.
54  * @note If the system supports monotonic clocks (and this library is
55  * not being cross-compiled onto a different architecture), then a
56  * system monotonic clock will be used in
57  * Cgu::Thread::Cond::timed_wait() and
58  * Cgu::Thread::Cond::get_abs_time(). This can be tested at run time
59  * with Cgu::Thread::Cond::have_monotonic_clock().
60  */
61 
62 namespace Cgu {
63 
64 namespace Thread {
65 
66 struct CondError: public std::exception {
67  virtual const char* what() const throw() {return "Thread::CondError";}
68 };
69 
70 /*
71  * Since version 1.2.0, which automatically checks for monotonic
72  * clocks in its configure script, this exception is no longer thrown.
73  * We keep the class just for source compatibility purposes.
74  */
75 #ifndef DOXYGEN_PARSING
76 struct CondSetClockError: public std::exception {
77  virtual const char* what() const throw() {return "Thread::CondSetClockError";}
78 };
79 #endif
80 
81 struct MutexError: public std::exception {
82  virtual const char* what() const throw() {return "Thread::MutexError";}
83 };
84 
85 struct RecMutexError: public std::exception {
86  virtual const char* what() const throw() {return "Thread::RecMutexError";}
87 };
88 
89 class Cond;
90 
91 /**
92  * @class Mutex mutex.h c++-gtk-utils/mutex.h
93  * @brief A wrapper class for pthread mutexes.
94  * @sa Thread::Thread Thread::Mutex::Lock Thread::Mutex::TrackLock Thread::Cond Thread::RecMutex
95  *
96  * This class can be used interchangeably with threads started with
97  * GThread and by this library, as both glib and this library use
98  * pthreads underneath on POSIX and other unix-like OSes. It can also
99  * in practice be used interchangeably with those started by C++11/14
100  * std::thread and with std::mutex and similar objects, as in C++11/14
101  * on unix-like OSes these facilities will be built on top of pthreads
102  * (for which purpose C++11/14 provides the std::native_handle_type
103  * type and std::thread::native_handle() function), or if they are
104  * not, they will use the same threading primitives provided by the
105  * kernel.
106  *
107  * Mutex objects can be constructed statically as well as dynamically
108  * and there is no need to call g_thread_init() before they are
109  * constructed, even if glib < 2.32 is used. (If created as a static
110  * object in global scope, it will not be possible to catch
111  * Thread::MutexError thrown by its constructor, but if a static
112  * global mutex throws there is nothing that could be done anyway
113  * except abort, and it would show that the pthreads installation is
114  * seriously defective.)
115  */
116 
117 class Mutex {
118  pthread_mutex_t pthr_mutex;
119 
120 public:
121  class Lock;
122  class TrackLock;
123  friend class Cond;
124 
125 /**
126  * This class cannot be copied. The copy constructor is deleted.
127  */
128  Mutex(const Mutex&) = delete;
129 
130 /**
131  * This class cannot be copied. The assignment operator is deleted.
132  */
133  Mutex& operator=(const Mutex&) = delete;
134 
135 /**
136  * Locks the mutex and acquires ownership. Blocks if already locked
137  * until it becomes free. It is not a cancellation point. It does
138  * not throw. It is thread safe.
139  * @return 0 if successful, otherwise the pthread mutex error number.
140  * @note With this library implementation, the only pthread error
141  * number which could be returned by this method is EDEADLK, which it
142  * would do if the default pthread mutex behaviour happens to return
143  * that error rather than deadlock in the case of recursive locking.
144  * Most default implementations do not do this and hence the return
145  * value is usually not worth checking for except during debugging.
146  */
147  int lock() {return pthread_mutex_lock(&pthr_mutex);}
148 
149 /**
150  * Tries to lock the mutex and acquire ownership, but returns
151  * immediately if it is already locked with value EBUSY. It is not a
152  * cancellation point. It does not throw. It is thread safe.
153  * @return 0 if successful, otherwise EBUSY.
154  * @note With this library implementation, the only pthread error
155  * number which could be returned by this method is EBUSY.
156  */
157  int trylock() {return pthread_mutex_trylock(&pthr_mutex);}
158 
159 /**
160  * Unlocks a locked mutex owned by the calling thread and relinquishes
161  * ownership. It is not a cancellation point. It does not throw. It
162  * must be called by the thread which owns the mutex.
163  * @return 0 if successful, otherwise the pthread mutex error number.
164  * @note With this library implementation, the only pthread error
165  * number which could be returned by this method is EPERM because the
166  * calling thread does not own the mutex (however POSIX does not
167  * require that return value in that case and hence the return value
168  * is usually not worth checking for except during debugging).
169  */
170  int unlock() {return pthread_mutex_unlock(&pthr_mutex);}
171 
172 /**
173  * Initialises the pthread mutex. It is not a cancellation point.
174  * @exception Cgu::Thread::MutexError Throws this exception if
175  * initialization of the mutex fails. (It is often not worth checking
176  * for this, as it means either memory is exhausted or pthread has run
177  * out of other resources to create new mutexes.)
178  */
179  Mutex() {if (pthread_mutex_init(&pthr_mutex, 0)) throw MutexError();}
180 
181 /**
182  * Destroys the pthread mutex. It is not a cancellation point. It
183  * does not throw. Destroying a mutex which is currently locked or
184  * associated with an active condition variable wait results in
185  * undefined behavior.
186  */
187  ~Mutex() {pthread_mutex_destroy(&pthr_mutex);}
188 
189 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
191 #endif
192 };
193 
194 // used as a second argument to Lock::Lock() and TrackLock::TrackLock
195 // in cases where the mutex has already been locked (say by Mutex::trylock())
196 enum Locked {locked};
197 // used as a second argument to TrackLock::TrackLock() in cases where
198 // locking of the mutex is to be deferred
200 
201 /**
202  * @class Mutex::Lock mutex.h c++-gtk-utils/mutex.h
203  * @brief A scoped locking class for exception safe Mutex locking.
204  * @sa Thread::Mutex Thread::Mutex::TrackLock Thread::Thread Thread::Cond
205  */
206 
207 class Mutex::Lock {
208  Mutex& mutex;
209 
210 public:
211  friend class Cond;
212 
213 /**
214  * This class cannot be copied. The copy constructor is deleted.
215  */
216  Lock(const Mutex::Lock&) = delete;
217 
218 /**
219  * This class cannot be copied. The assignment operator is deleted.
220  */
221  Mutex::Lock& operator=(const Mutex::Lock&) = delete;
222 
223 /**
224  * Calls Mutex::lock(), and so locks the mutex and reacquires
225  * ownership. It blocks if the mutex is already locked until the
226  * mutex becomes free. This method should normally only be called if
227  * a previous call has been made to Mutex::Lock::unlock() (that is,
228  * where the thread owning the Mutex::Lock object has temporarily
229  * allowed another thread to take the mutex concerned). It is not a
230  * cancellation point. It does not throw.
231  * @return 0 if successful, otherwise the pthread mutex error number.
232  * @note With this library implementation, the only pthread error
233  * number which could be returned by this method is EDEADLK, which it
234  * would do if the default pthread mutex behaviour happens to return
235  * that error rather than deadlock in the case of recursive locking.
236  * Most default implementations do not do this and hence the return
237  * value is usually not worth checking for except during debugging.
238  * @sa Mutex::TrackLock.
239  */
240  int lock() {return mutex.lock();}
241 
242 /**
243  * Calls Mutex::trylock(), and so tries to lock the mutex and
244  * reacquire ownership, but returns immediately if it is already
245  * locked with value EBUSY. This method should normally only be
246  * called if a previous call has been made to Mutex::Lock::unlock()
247  * (that is, where the thread owning the Mutex::Lock object has
248  * temporarily allowed another thread to take the mutex concerned).
249  * It is not a cancellation point. It does not throw.
250  * @return 0 if successful, otherwise EBUSY.
251  * @note With this library implementation, the only pthread error
252  * number which could be returned by this method is EBUSY.
253  * @sa Mutex::TrackLock.
254  */
255  int trylock() {return mutex.trylock();}
256 
257 /**
258  * Calls Mutex::unlock(), and so unlocks a locked mutex owned by the
259  * calling thread and relinquishes ownership (so temporarily allowing
260  * another thread to take the mutex). This method should normally
261  * only be called if it is to be followed by a call to
262  * Mutex::Lock::lock() or a successful call to Mutex::Lock::trylock()
263  * before the Mutex::Lock object concerned goes out of scope
264  * (otherwise Mutex::Lock's destructor will attempt to unlock an
265  * already unlocked mutex or a mutex of which another thread has by
266  * then taken ownership - Mutex::Lock objects do not maintain state).
267  * See Mutex::TrackLock::unlock() for a safe version of this method.
268  * It is not a cancellation point. It does not throw.
269  * @return 0 if successful, otherwise the pthread mutex error number.
270  * @note With this library implementation, the only pthread error
271  * number which could be returned by this method is EPERM because the
272  * calling thread does not own the mutex (however POSIX does not
273  * require that return value in that case and hence the return value
274  * is usually not worth checking for except during debugging).
275  * @sa Mutex::TrackLock.
276  */
277  int unlock() {return mutex.unlock();}
278 
279 /**
280  * This constructor locks the mutex passed to it. It is not a
281  * cancellation point. It does not throw.
282  * @param mutex_ The mutex to be locked.
283  */
284  Lock(Mutex& mutex_): mutex(mutex_) {mutex.lock();}
285 
286 /**
287  * This constructor takes an already locked mutex (say as a result of
288  * Mutex::trylock()), and takes ownership of it. It is not a
289  * cancellation point. It does not throw.
290  * @param mutex_ The mutex to be managed by this object.
291  * @param tag Pass the Cgu::Thread::locked enum tag to this parameter.
292  */
293  Lock(Mutex& mutex_, Locked tag): mutex(mutex_) {}
294 
295 /**
296  * This class requires initialisation with a Mutex. The default
297  * constructor is deleted.
298  */
299  Lock() = delete;
300 
301 /**
302  * The destructor unlocks the owned mutex. It is not a cancellation
303  * point. It does not throw.
304  */
305  ~Lock() {mutex.unlock();}
306 
307 /* Only has effect if --with-glib-memory-slices-compat or
308  * --with-glib-memory-slices-no-compat option picked */
310 };
311 
312 /**
313  * @class Mutex::TrackLock mutex.h c++-gtk-utils/mutex.h
314  * @brief A scoped locking class for exception safe Mutex locking
315  * which tracks the status of its mutex.
316  * @sa Thread::Mutex Thread::Mutex::Lock Thread::Thread Thread::Cond
317  *
318  * This class is similar to a Mutex::Lock object, except that it
319  * tracks whether the mutex it manages is locked by the thread
320  * creating the Mutex::TrackLock object (provided that, while the
321  * Mutex::TrackLock object exists, the thread creating it only
322  * accesses the mutex through that object). This enables
323  * Mutex::TrackLock::unlock() to be used without it being followed
324  * later by a call to Mutex::TrackLock::lock() or a successful call to
325  * Mutex::TrackLock::trylock(), and also permits locking to be
326  * deferred until after construction of the lock object. Note that
327  * only one thread may call the methods of any one Mutex::TrackLock
328  * object, including causing its destructor to be invoked.
329  */
330 
332  Mutex& mutex;
333  bool owner;
334 
335 public:
336  friend class Cond;
337 
338 /**
339  * This class cannot be copied. The copy constructor is deleted.
340  */
341  TrackLock(const Mutex::TrackLock&) = delete;
342 
343 /**
344  * This class cannot be copied. The assignment operator is deleted.
345  */
346  Mutex::TrackLock& operator=(const Mutex::TrackLock&) = delete;
347 
348 /**
349  * Calls Mutex::lock(), and so locks the mutex and acquires ownership.
350  * It blocks if the mutex is already locked until the mutex becomes
351  * free. This method should normally only be called if a previous
352  * call has been made to Mutex::TrackLock::unlock() or this
353  * Mutex::TrackLock object has been constructed with the Thread::defer
354  * enum tag. It is not a cancellation point. It does not throw.
355  * @return 0 if successful, otherwise the pthread mutex error number.
356  * @note With this library implementation, the only pthread error
357  * number which could be returned by this method is EDEADLK, which it
358  * would do if the default pthread mutex behaviour happens to return
359  * that error rather than deadlock in the case of recursive locking.
360  * Most default implementations do not do this and hence the return
361  * value is usually not worth checking for except during debugging.
362  */
363  int lock() {int ret = mutex.lock(); if (!owner) owner = !ret; return ret;}
364 
365 /**
366  * Calls Mutex::trylock(), and so tries to lock the mutex and acquire
367  * ownership, but returns immediately if it is already locked with
368  * value EBUSY. This method should normally only be called if a
369  * previous call has been made to Mutex::TrackLock::unlock() or this
370  * Mutex::TrackLock object has been constructed with the Thread::defer
371  * enum tag. It is not a cancellation point. It does not throw.
372  * @return 0 if successful, otherwise EBUSY.
373  * @note With this library implementation, the only pthread error
374  * number which could be returned by this method is EBUSY.
375  */
376  int trylock() {int ret = mutex.trylock(); if (!owner) owner = !ret; return ret;}
377 
378 /**
379  * Calls Mutex::unlock(), and so unlocks a locked mutex owned by the
380  * calling thread. It will cause is_owner() to return false unless a
381  * subsequent call is made to lock() or a subsequent successful call
382  * is made to trylock(). It is not a cancellation point. It does not
383  * throw.
384  * @return 0 if successful, otherwise the pthread mutex error number.
385  * @note With this library implementation, the only pthread error
386  * number which could be returned by this method is EPERM because the
387  * calling thread does not own the mutex (however POSIX does not
388  * require that return value in that case and hence the return value
389  * is usually not worth checking for except during debugging).
390  */
391  int unlock() {int ret = mutex.unlock(); if (owner) owner = ret; return ret;}
392 
393 /**
394  * Indicates whether the mutex managed by this Mutex::TrackLock object
395  * is locked, and so owned, by it. It does not throw.
396  * @return true if the mutex is locked by this object, otherwise
397  * false.
398  */
399  bool is_owner() const {return owner;}
400 
401 /**
402  * This constructor locks the mutex passed to it. It is not a
403  * cancellation point. It does not throw.
404  * @param mutex_ The mutex to be locked.
405  */
406  TrackLock(Mutex& mutex_): mutex(mutex_), owner(true) {mutex.lock();}
407 
408 /**
409  * This constructor takes an already locked mutex (say as a result of
410  * Mutex::trylock()), and takes ownership of it. It is not a
411  * cancellation point. It does not throw.
412  * @param mutex_ The mutex to be managed by this object.
413  * @param tag Pass the Cgu::Thread::locked enum tag to this parameter.
414  */
415  TrackLock(Mutex& mutex_, Locked tag): mutex(mutex_), owner(true) {}
416 
417 /**
418  * This constructor defers locking of the mutex (and so taking
419  * ownership of it) until an explicit call to lock() or trylock() is
420  * made. It is not a cancellation point. It does not throw.
421  * @param mutex_ The mutex to be managed by this object.
422  * @param tag Pass the Cgu::Thread::defer enum tag to this parameter.
423  */
424  TrackLock(Mutex& mutex_, DeferLock tag): mutex(mutex_), owner(false) {}
425 
426 /**
427  * This class requires initialisation with a Mutex. The default
428  * constructor is deleted.
429  */
430  TrackLock() = delete;
431 
432 /**
433  * The destructor unlocks the managed mutex if it is locked. It is
434  * not a cancellation point. It does not throw.
435  */
436  ~TrackLock() {if (owner) mutex.unlock();}
437 
438 /* Only has effect if --with-glib-memory-slices-compat or
439  * --with-glib-memory-slices-no-compat option picked */
441 };
442 
443 /**
444  * @class Cond mutex.h c++-gtk-utils/mutex.h
445  * @brief A wrapper class for pthread condition variables.
446  * @sa Thread::Thread Thread::Mutex Thread::Mutex::Lock Thread::Mutex::TrackLock
447  */
448 
449 class Cond {
450  pthread_cond_t cond;
451 
452 public:
453 
454 /**
455  * This class cannot be copied. The copy constructor is deleted.
456  */
457  Cond(const Cond&) = delete;
458 
459 /**
460  * This class cannot be copied. The assignment operator is deleted.
461  */
462  Cond& operator=(const Cond&) = delete;
463 
464 /**
465  * Unblock at least one thread waiting on this condition variable.
466  * Can be called by any thread. It is not a cancellation point. Does
467  * not throw.
468  * @return 0 if successful, otherwise the pthread error number.
469  * @note With this library implementation, no pthread error should
470  * arise so there is no need to check the return value.
471  */
472  int signal() {return pthread_cond_signal(&cond);}
473 
474 /**
475  * Unblocks all threads waiting on this condition variable, which
476  * acquire the mutex in an order determined by the scheduling policy.
477  * Can be called by any thread. It is not a cancellation point. Does
478  * not throw.
479  * @return 0 if successful, otherwise the pthread error number.
480  * @note With this library implementation, no pthread error should
481  * arise so there is no need to check the return value.
482  */
483  int broadcast() {return pthread_cond_broadcast(&cond);}
484 
485 /**
486  * Waits on this condition variable until awoken. It must be called
487  * by the thread which owns the mutex. Re-acquires the mutex when
488  * awoken. It is a cancellation point. This method is cancellation
489  * safe even if the stack does not unwind on cancellation (but if the
490  * stack does not unwind some other way of destroying this object on
491  * cancellation is required, such as by having it allocated on
492  * freestore and deleted in a cancellation clean-up handler). This
493  * method does not throw.
494  * @param mutex The locked mutex associated with the wait which is
495  * re-acquired on being awoken.
496  * @return 0 after being awoken on waiting, otherwise the pthread
497  * error number.
498  * @note 1. pthread condition variables can, as a matter of design,
499  * awake spontaneously (and Cond::signal() may awaken more than one
500  * thread). Therefore the relevant condition should be tested in a
501  * while loop and not in an if block. 0 will be returned on a
502  * spontaneous awakening.
503  * @note 2. With this library implementation, the only pthread error
504  * numbers which could be returned are EINVAL (if the mutex argument
505  * is not a valid mutex) or EPERM (if the thread calling this method
506  * does not own the mutex).
507  */
508  int wait(Mutex& mutex) {return pthread_cond_wait(&cond, &mutex.pthr_mutex);}
509 
510 /**
511  * Does the same as Cond::wait(Mutex&), except that as a convenience
512  * it will take a Mutex::Lock object handling the Mutex object as an
513  * alternative to passing the Mutex object itself.
514  */
515  int wait(Mutex::Lock& lock) {return wait(lock.mutex);}
516 
517 /**
518  * Does the same as Cond::wait(Mutex&), except that as a convenience
519  * it will take a Mutex::TrackLock object handling the Mutex object as
520  * an alternative to passing the Mutex object itself.
521  */
522  int wait(Mutex::TrackLock& lock) {return wait(lock.mutex);}
523 
524 /**
525  * Waits on this condition variable until awoken (in which case it
526  * re-acquires the mutex), or until the timeout expires (in which case
527  * it re-acquires the mutex and returns with ETIMEDOUT). It must be
528  * called by the thread which owns the mutex. Re-acquires the mutex
529  * when awoken or timing out. It is a cancellation point. This
530  * method is cancellation safe even if the stack does not unwind on
531  * cancellation (but if the stack does not unwind some other way of
532  * destroying this object on cancellation is required, such as by
533  * having it allocated on freestore and deleted in a cancellation
534  * clean-up handler). This method does not throw.
535  * @param mutex The locked mutex associated with the wait which is
536  * re-acquired on being awoken or timing out.
537  * @param abs_time The time at which the wait will unblock if not
538  * previously awoken. A suitable value can be obtained by calling
539  * the get_abs_time() function.
540  * @return 0 after being awoken on waiting, otherwise ETIMEDOUT or
541  * other pthread error number.
542  * @note 1. With this library implementation, apart from ETIMEDOUT,
543  * the only pthread error numbers which could be returned are EINVAL
544  * (if the mutex argument is not a valid mutex or the abs_time
545  * argument does not comprise a valid timespec struct) or EPERM (if
546  * the thread calling this method does not own the mutex).
547  * @note 2. pthread condition variables can, as a matter of design,
548  * awake spontaneously (and Cond::signal() may awaken more than one
549  * thread). Therefore the relevant condition should be tested in a
550  * while loop and not in an if block. 0 will be returned on a
551  * spontaneous awakening.
552  * @note 3. If the system supports monotonic clocks (and this library
553  * is not being cross-compiled onto a different architecture), then
554  * condition variables will use a monotonic clock in
555  * Cond::timed_wait() and Cond::get_abs_time(). This can be tested at
556  * run time with Cond::have_monotonic_clock().
557  */
558  int timed_wait(Mutex& mutex, const timespec& abs_time) {
559  return pthread_cond_timedwait(&cond, &mutex.pthr_mutex, &abs_time);
560  }
561 
562 /**
563  * Does the same as Cond::timed_wait(Mutex&, const timespec&), except
564  * that as a convenience it will take a Mutex::Lock object handling
565  * the Mutex object as an alternative to passing the Mutex object
566  * itself.
567  */
569  const timespec& abs_time) {return timed_wait(lock.mutex, abs_time);}
570 
571 /**
572  * Does the same as Cond::timed_wait(Mutex&, const timespec&), except
573  * that as a convenience it will take a Mutex::TrackLock object
574  * handling the Mutex object as an alternative to passing the Mutex
575  * object itself.
576  */
578  const timespec& abs_time) {return timed_wait(lock.mutex, abs_time);}
579 
580 /**
581  * This is a utility function that inserts into a timespec structure
582  * the current time plus a given number of milliseconds ahead, which
583  * can be applied to a call to Cond::timed_wait(). It does not throw.
584  * It is thread-safe.
585  * @param ts A timespec object into which the result of current time +
586  * millisec will be placed.
587  * @param millisec The number of milliseconds ahead of current time to
588  * which the timespec object will be set.
589  * @note If the system supports monotonic clocks (and this library is
590  * not being cross-compiled onto a different architecture), then
591  * condition variables will use a system monotonic clock in this
592  * method and Cond::timed_wait(). This can be tested at run time with
593  * Cond::have_monotonic_clock().
594  */
595  static void get_abs_time(timespec& ts, unsigned int millisec);
596 
597 /**
598  * Indicates whether the library has been compiled with support for
599  * monotonic clocks in Cond::timed_wait(). Most recent linux and BSD
600  * distributions will support them, and this function would normally
601  * return true unless the library has been cross-compiled from one
602  * platform to a different platform. This function can be tested at
603  * program initialization, and if they are not supported a warning can
604  * be given to the user about the deficiences of using the system
605  * clock for timed events. It does not throw. It is thread safe.
606  * @return true if the library has been compiled with support for
607  * monotonic clocks in Cond::timed_wait(), otherwise false.
608  */
609  static bool have_monotonic_clock();
610 
611 /**
612  * Initialises the pthread condition variable. It is not a
613  * cancellation point.
614  * @exception Cgu::Thread::CondError Throws this exception if
615  * initialization of the condition variable fails. (It is often not
616  * worth checking for CondError, as it means either memory is
617  * exhausted or pthread has run out of other resources to create new
618  * condition variables.)
619  * @note If the system supports monotonic clocks (and this library is
620  * not being cross-compiled onto a different architecture), then
621  * condition variables will use a system monotonic clock in
622  * Cond::timed_wait() and Cond::get_abs_time(). This can be tested at
623  * run time by calling Cond::have_monotonic_clock().
624  */
625  Cond();
626 
627 /**
628  * Destroys the pthread condition variable. It is not a cancellation
629  * point. The destructor does not throw. Destroying a condition
630  * variable on which another thread is currently blocked results in
631  * undefined behavior.
632  */
633  ~Cond(void) {pthread_cond_destroy(&cond);}
634 
635 /* Only has effect if --with-glib-memory-slices-compat or
636  * --with-glib-memory-slices-no-compat option picked */
638 };
639 
640 /**
641  * @class RecMutex mutex.h c++-gtk-utils/mutex.h
642  * @brief A wrapper class for pthread mutexes which provides a
643  * recursive mutex.
644  * @sa Thread::Thread Thread::RecMutex::Lock Thread::RecMutex::TrackLock Thread::Mutex
645  *
646  * This class can be used interchangeably with threads started with
647  * GThread and by this library, as both glib and this library use
648  * pthreads underneath on POSIX and other unix-like OSes. It can also
649  * in practice be used interchangeably with those started by C++11/14
650  * std::thread and with std::recursive_mutex and similar objects, as
651  * in C++11/14 on unix-like OSes these facilities will be built on top
652  * of pthreads (for which purpose C++11/14 provides the
653  * std::native_handle_type type and std::thread::native_handle()
654  * function), or if they are not, they will use the same threading
655  * primitives provided by the kernel.
656  *
657  * RecMutex objects can be constructed statically as well as
658  * dynamically and there is no need to call g_thread_init() before
659  * they are constructed, even if glib < 2.32 is used. (If created as
660  * a static object in global scope, it will not be possible to catch
661  * Thread::MutexError or Thread::RecMutexError thrown by its
662  * constructor, but if a static global mutex throws there is nothing
663  * that could be done anyway except abort.)
664  *
665  * See the comments below on the test_support() method of this class,
666  * about how the system's support for native recursive mutexes can be
667  * tested at runtime and when a user program is compiled. If glib >=
668  * 2.32 is installed, it can be assumed that native recursive mutexes
669  * are available, as glib >= 2.32 also uses them.
670  */
671 
672 class RecMutex {
673  pthread_mutex_t pthr_mutex;
674 
675 public:
676  class Lock;
677  class TrackLock;
678 
679 /**
680  * This class cannot be copied. The copy constructor is deleted.
681  */
682  RecMutex(const RecMutex&) = delete;
683 
684 /**
685  * This class cannot be copied. The assignment operator is deleted.
686  */
687  RecMutex& operator=(const RecMutex&) = delete;
688 
689 /**
690  * Locks the mutex and acquires ownership. Blocks if already locked
691  * until it becomes free, unless the calling thread already holds the
692  * lock, in which case it increments the lock count and returns
693  * immediately. It is not a cancellation point. It does not throw.
694  * It is thread safe.
695  * @return 0 if successful, otherwise the pthread mutex error number.
696  * @note With this library implementation, the only pthread error
697  * number which could be returned by this method is EAGAIN, which it
698  * would do if the maximum recursive lock count for this mutex has
699  * been reached. Usually this number is at or around INT_MAX and
700  * hence the return value is usually not worth checking for except
701  * during debugging.
702  */
703  int lock() {return pthread_mutex_lock(&pthr_mutex);}
704 
705 /**
706  * Tries to lock the mutex and acquire ownership, but returns
707  * immediately if it is already locked with value EBUSY unless the
708  * calling thread already holds the lock, in which case it returns
709  * normally and increments the lock count. It is not a cancellation
710  * point. It does not throw. It is thread safe.
711  * @return 0 if successful, otherwise EBUSY or other pthread mutex
712  * error number.
713  * @note With this library implementation, apart from EBUSY, the only
714  * other pthread error number which could be returned by this method
715  * is EAGAIN, which it would do if the maximum recursive lock count
716  * for this mutex has been reached. Usually this number is at or
717  * around INT_MAX and hence an EAGAIN error return value is usually
718  * not worth checking for except during debugging.
719  */
720  int trylock() {return pthread_mutex_trylock(&pthr_mutex);}
721 
722 /**
723  * Unlocks a locked mutex owned by the calling thread and either
724  * relinquishes ownership (if the mutex has not been recursively
725  * locked) or decrements the lock count (if it has). It is not a
726  * cancellation point. It does not throw. It must be called by the
727  * thread which owns the mutex.
728  * @return 0 if successful, otherwise the pthread mutex error number.
729  * @note With this library implementation, the only pthread error
730  * number which could be returned by this method is EPERM because the
731  * calling thread does not own the mutex (however POSIX does not
732  * require that return value in that case and hence the return value
733  * is usually not worth checking for except during debugging).
734  */
735  int unlock() {return pthread_mutex_unlock(&pthr_mutex);}
736 
737 /**
738  * Indicates whether the system supports recursive mutexes. This
739  * method does not throw. It is thread safe.
740  * @return 0 if the system supports recursive mutexes, -1 if it does
741  * not support recursive mutexes and 1 if pthread has run out of
742  * sufficient resources to test this at run time (in which case any
743  * attempt to create mutexes or start threads is likely to fail).
744  * Practically all recent linux and BSD distributions will support
745  * them, and this function would normally return 0. If it does not,
746  * it is still possible to use GStaticRecMutex objects (for which
747  * purpose see Cgu::Thread::GrecmutexLock).
748  *
749  * @note The header file <c++-gtk-utils/cgu_config.h> defines the
750  * symbol CGU_HAVE_RECURSIVE_MUTEX if native recursive mutexes were
751  * found to be supported when this library was compiled. Programs
752  * using this library can therefore test for that symbol with the
753  * pre-processor for conditional compilation purposes (so that the
754  * program can, for example, be compiled to use GStaticRecMutex if
755  * that symbol is not defined). However, if the library was
756  * cross-compiled from one architecture to another, that symbol may
757  * not be defined even though the target architecture does, in fact,
758  * support them at program runtime. In other words, if
759  * CGU_HAVE_RECURSIVE_MUTEX is defined then this method will always
760  * return 0; but in the event of cross-compilation of the library this
761  * method (which provides a separate runtime test) might return 0,
762  * correctly showing support, even when CGU_HAVE_RECURSIVE_MUTEX is
763  * not defined.
764  *
765  * @note If glib >= 2.32 is installed, it can be assumed that native
766  * recursive mutexes are available, as glib >= 2.32 also uses them.
767  */
768  static int test_support();
769 
770 /**
771  * Initialises the pthread mutex. It is not a cancellation point.
772  * @exception Cgu::Thread::RecMutexError Throws this exception if the
773  * system does not support recursive mutexes. (If this has been
774  * checked beforehand, say by calling test_support(), there should be
775  * no need to check for this exception.)
776  * @exception Cgu::Thread::MutexError Throws this exception if
777  * initialization of the mutex fails, except because the system does
778  * not support recursive mutexes. (It is often not worth checking for
779  * MutexError, as it means either memory is exhausted or pthread has
780  * run out of other resources to create new mutexes.)
781  */
782  RecMutex();
783 
784 /**
785  * Destroys the pthread mutex. It is not a cancellation point. It
786  * does not throw. Destroying a mutex which is currently locked
787  * results in undefined behavior.
788  */
789  ~RecMutex() {pthread_mutex_destroy(&pthr_mutex);}
790 
791 /* Only has effect if --with-glib-memory-slices-compat or
792  * --with-glib-memory-slices-no-compat option picked */
794 };
795 
796 /**
797  * @class RecMutex::Lock mutex.h c++-gtk-utils/mutex.h
798  * @brief A scoped locking class for exception safe RecMutex locking.
799  * @sa Thread::RecMutex Thread::RecMutex::TrackLock Thread::Thread
800  */
801 
803  RecMutex& mutex;
804 
805 public:
806 /**
807  * This class cannot be copied. The copy constructor is deleted.
808  */
809  Lock(const RecMutex::Lock&) = delete;
810 
811 /**
812  * This class cannot be copied. The assignment operator is deleted.
813  */
814  RecMutex::Lock& operator=(const RecMutex::Lock&) = delete;
815 
816 /**
817  * This calls RecMutex::lock(), and so locks the mutex and reacquires
818  * ownership. It blocks if the mutex is already locked until the
819  * mutex becomes free, unless the calling thread already holds the
820  * lock, in which case it increments the lock count and returns
821  * immediately. This method should normally only be called if a
822  * previous call has been made to RecMutex::Lock::unlock() (that is,
823  * where the thread owning the RecMutex::Lock object has temporarily
824  * allowed another thread to take the mutex concerned if it is not
825  * recursively locked). It is not a cancellation point. It does not
826  * throw.
827  * @return 0 if successful, otherwise the pthread mutex error number.
828  * @note With this library implementation, the only pthread error
829  * number which could be returned by this method is EAGAIN, which it
830  * would do if the maximum recursive lock count for the particular
831  * mutex in question has been reached. Usually this number is at or
832  * around INT_MAX and hence the return value is usually not worth
833  * checking for except during debugging.
834  * @sa RecMutex::TrackLock.
835  */
836  int lock() {return mutex.lock();}
837 
838 /**
839  * This calls RecMutex::trylock(), and so tries to lock the mutex and
840  * reacquire ownership, but returns immediately if it is already
841  * locked with value EBUSY unless the calling thread already holds the
842  * lock, in which case it returns normally and increments the lock
843  * count. This method should normally only be called if a previous
844  * call has been made to RecMutex::Lock::unlock() (that is, where the
845  * thread owning the RecMutex::Lock object has temporarily allowed
846  * another thread to take the mutex concerned if it is not recursively
847  * locked). It is not a cancellation point. It does not throw.
848  * @return 0 if successful, otherwise EBUSY or other pthread mutex
849  * error number.
850  * @note With this library implementation, apart from EBUSY, the only
851  * other pthread error number which could be returned by this method
852  * is EAGAIN, which it would do if the maximum recursive lock count
853  * for the particular mutex in question has been reached. Usually
854  * this number is at or around INT_MAX and hence an EAGAIN error
855  * return value is usually not worth checking for except during
856  * debugging.
857  * @sa RecMutex::TrackLock.
858  */
859  int trylock() {return mutex.trylock();}
860 
861 /**
862  * This calls RecMutex::unlock() and so unlocks a locked mutex owned
863  * by the calling thread, so temporarily allowing another thread to
864  * take the mutex if the mutex has not been recursively locked, or if
865  * it has been recursively locked decrements the lock count, so
866  * temporarily relinquishing ownership. This method should normally
867  * only be called if it is to be followed by a call to
868  * RecMutex::Lock::lock() or a successful call to
869  * RecMutex::Lock::trylock() before the RecMutex::Lock object
870  * concerned goes out of scope (otherwise RecMutex::Lock's destructor
871  * will attempt to decrement the lock count of a mutex which already
872  * has a lock count of 0 or which another thread has by then taken
873  * ownership or leave the lock count in an unbalanced condition -
874  * RecMutex::Lock objects do not maintain state). See
875  * RecMutex::TrackLock::unlock() for a safe version of this method.
876  * It is not a cancellation point. It does not throw.
877  * @return 0 if successful, otherwise the pthread mutex error number.
878  * @note With this library implementation, the only pthread error
879  * number which could be returned by this method is EPERM because the
880  * calling thread does not own the particular mutex in question
881  * (however POSIX does not require that return value in that case and
882  * hence the return value is usually not worth checking for except
883  * during debugging).
884  * @sa RecMutex::TrackLock.
885  */
886  int unlock() {return mutex.unlock();}
887 
888 /**
889  * This constructor locks the mutex passed to it. See
890  * RecMutex::lock() for a description of the outcomes. It is not a
891  * cancellation point.
892  * @param mutex_ The mutex to be locked.
893  * @exception Cgu::Thread::RecMutexError Throws this exception if
894  * initialization of the mutex fails because the maximum recursive
895  * lock count for the particular mutex in question has been reached.
896  * Usually this number is at or around INT_MAX so it is not usually
897  * useful to check for it except during debugging.
898  */
899  Lock(RecMutex& mutex_): mutex(mutex_) {if (mutex.lock()) throw RecMutexError();}
900 
901 /**
902  * This constructor takes an already locked mutex (say as a result of
903  * RecMutex::trylock()), and takes ownership of it. It is not a
904  * cancellation point. It does not throw.
905  * @param mutex_ The mutex to be managed by this object.
906  * @param tag Pass the Cgu::Thread::locked enum tag to this parameter.
907  */
908  Lock(RecMutex& mutex_, Locked tag): mutex(mutex_) {}
909 
910 /**
911  * This class requires initialisation with a RecMutex. The default
912  * constructor is deleted.
913  */
914  Lock() = delete;
915 
916 /**
917  * The destructor unlocks the owned mutex. See RecMutex::unlock() for
918  * a description of the outcomes. It is not a cancellation point. It
919  * does not throw.
920  */
921  ~Lock() {mutex.unlock();}
922 
923 /* Only has effect if --with-glib-memory-slices-compat or
924  * --with-glib-memory-slices-no-compat option picked */
926 };
927 
928 /**
929  * @class RecMutex::TrackLock mutex.h c++-gtk-utils/mutex.h
930  * @brief A scoped locking class for exception safe RecMutex locking
931  * which tracks the status of its mutex.
932  * @sa Thread::RecMutex Thread::RecMutex::Lock Thread::Thread
933  *
934  * This class is similar to a RecMutex::Lock object, except that it
935  * tracks whether the mutex it manages is locked by the thread
936  * creating the RecMutex::TrackLock object with respect to the
937  * particular locking operation to be governed by the object (provided
938  * that, while the RecMutex::TrackLock object exists, the thread
939  * creating it only accesses the mutex with respect that particular
940  * operation through that object). This enables
941  * RecMutex::TrackLock::unlock() to be used without it being followed
942  * later by a call to RecMutex::TrackLock::lock() or a successful call
943  * to RecMutex::TrackLock::trylock(), and also permits locking to be
944  * deferred until after construction of the lock object. Note that
945  * only one thread may call the methods of any one RecMutex::TrackLock
946  * object, including causing its destructor to be invoked.
947  */
948 
950  RecMutex& mutex;
951  bool owner;
952 
953 public:
954 
955 /**
956  * This class cannot be copied. The copy constructor is deleted.
957  */
958  TrackLock(const RecMutex::TrackLock&) = delete;
959 
960 /**
961  * This class cannot be copied. The assignment operator is deleted.
962  */
964 
965 /**
966  * This calls RecMutex::lock(), and so locks the mutex and acquires
967  * ownership. It blocks if the mutex is already locked until the
968  * mutex becomes free, unless the calling thread already holds the
969  * lock, in which case it increments the lock count and returns
970  * immediately. This method should normally only be called if a
971  * previous call has been made to RecMutex::TrackLock::unlock() or
972  * this RecMutex::TrackLock object has been constructed with the
973  * Thread::defer enum tag. It is not a cancellation point. It does
974  * not throw.
975  * @return 0 if successful, otherwise the pthread mutex error number.
976  * @note With this library implementation, the only pthread error
977  * number which could be returned by this method is EAGAIN, which it
978  * would do if the maximum recursive lock count for the particular
979  * mutex in question has been reached. Usually this number is at or
980  * around INT_MAX and hence the return value is usually not worth
981  * checking for except during debugging.
982  */
983  int lock() {int ret = mutex.lock(); if (!owner) owner = !ret; return ret;}
984 
985 /**
986  * This calls RecMutex::trylock(), and so tries to lock the mutex and
987  * acquire ownership, but returns immediately if it is already locked
988  * with value EBUSY unless the calling thread already holds the lock,
989  * in which case it returns normally and increments the lock count.
990  * This method should normally only be called if a previous call has
991  * been made to RecMutex::TrackLock::unlock() or this
992  * RecMutex::TrackLock object has been constructed with the
993  * Thread::defer enum tag. It is not a cancellation point. It does
994  * not throw.
995  * @return 0 if successful, otherwise EBUSY or other pthread mutex
996  * error number.
997  * @note With this library implementation, apart from EBUSY, the only
998  * other pthread error number which could be returned by this method
999  * is EAGAIN, which it would do if the maximum recursive lock count
1000  * for the particular mutex in question has been reached. Usually
1001  * this number is at or around INT_MAX and hence an EAGAIN error
1002  * return value is usually not worth checking for except during
1003  * debugging.
1004  */
1005  int trylock() {int ret = mutex.trylock(); if (!owner) owner = !ret; return ret;}
1006 
1007 /**
1008  * This calls RecMutex::unlock(), and so unlocks a locked mutex owned
1009  * by the calling thread, or decrements the lock count (if it has been
1010  * recursively locked). It will cause is_owner() to return false
1011  * unless a subsequent call is made to lock() or a subsequent
1012  * successful call is made to trylock(). It is not a cancellation
1013  * point. It does not throw.
1014  * @return 0 if successful, otherwise the pthread mutex error number.
1015  * @note With this library implementation, the only pthread error
1016  * number which could be returned by this method is EPERM because the
1017  * calling thread does not own the particular mutex in question
1018  * (however POSIX does not require that return value in that case and
1019  * hence the return value is usually not worth checking for except
1020  * during debugging).
1021  */
1022  int unlock() {int ret = mutex.unlock(); if (owner) owner = ret; return ret;}
1023 
1024 /**
1025  * Indicates whether the mutex managed by this Mutex::TrackLock object
1026  * is locked by it (whether originally or recursively) and so owned by
1027  * it. It does not throw.
1028  * @return true if the mutex is owned by this object, otherwise false.
1029  */
1030  bool is_owner() const {return owner;}
1031 
1032 /**
1033  * This constructor locks the mutex passed to it. See
1034  * RecMutex::lock() for a description of the outcomes. It is not a
1035  * cancellation point. It does not throw.
1036  * @param mutex_ The mutex to be locked.
1037  * @exception Cgu::Thread::RecMutexError Throws this exception if
1038  * initialization of the mutex fails because the maximum recursive
1039  * lock count for the particular mutex in question has been reached.
1040  * Usually this number is at or around INT_MAX so it is not usually
1041  * useful to check for it except during debugging.
1042  */
1043  TrackLock(RecMutex& mutex_): mutex(mutex_), owner(true) {if (mutex.lock()) throw RecMutexError();}
1044 
1045 /**
1046  * This constructor takes an already locked mutex (say as a result of
1047  * RecMutex::trylock()), and takes ownership of it. It is not a
1048  * cancellation point. It does not throw.
1049  * @param mutex_ The mutex to be managed by this object.
1050  * @param tag Pass the Cgu::Thread::locked enum tag to this parameter.
1051  */
1052  TrackLock(RecMutex& mutex_, Locked tag): mutex(mutex_), owner(true) {}
1053 
1054 /**
1055  * This constructor defers locking of the mutex (and so taking
1056  * ownership of it) until an explicit call to lock() or trylock() is
1057  * made. It is not a cancellation point. It does not throw.
1058  * @param mutex_ The mutex to be managed by this object.
1059  * @param tag Pass the Cgu::Thread::defer enum tag to this parameter.
1060  */
1061  TrackLock(RecMutex& mutex_, DeferLock tag): mutex(mutex_), owner(false) {}
1062 
1063 /**
1064  * This class requires initialisation with a RecMutex. The default
1065  * constructor is deleted.
1066  */
1067  TrackLock() = delete;
1068 
1069 /**
1070  * The destructor unlocks the managed mutex if it is owned by this
1071  * RecMutex::TrackLock object. See RecMutex::unlock() for a
1072  * description of the outcomes if it is so owned. It is not a
1073  * cancellation point. It does not throw.
1074  */
1075  ~TrackLock() {if (owner) mutex.unlock();}
1076 
1077 /* Only has effect if --with-glib-memory-slices-compat or
1078  * --with-glib-memory-slices-no-compat option picked */
1080 };
1081 
1082 // we don't want glib's warnings about GStaticRecMutex
1083 #ifdef CGU_USE_DIAGNOSTIC_PRAGMAS
1084 #pragma GCC diagnostic push
1085 #pragma GCC diagnostic ignored "-Wdeprecated-declarations"
1086 #endif
1087 
1088 /**
1089  * @class GrecmutexLock mutex.h c++-gtk-utils/mutex.h
1090  * @brief A scoped locking class for exception safe locking of
1091  * GStaticRecMutex objects.
1092  * @details This class is mainly intended for use where the native
1093  * pthreads implementation does not support recursive mutexes so
1094  * Cgu::Thread::RecMutex and Cgu::Thread::RecMutex::Lock cannot be
1095  * used.
1096  *
1097  * It should be noted that this class is for use with GStaticRecMutex
1098  * objects, and not the GRecMutex objects available in glib from glib
1099  * version 2.32. If glib >= 2.32 is installed, it can be assumed that
1100  * native recursive mutexes and so Cgu::Thread::RecMutex are
1101  * available, as glib >= 2.32 also uses native recursive mutexes.
1102  */
1104  GStaticRecMutex& mutex;
1105 public:
1106 
1107 /**
1108  * This class cannot be copied. The copy constructor is deleted.
1109  */
1110  GrecmutexLock(const GrecmutexLock&) = delete;
1111 
1112 /**
1113  * This class cannot be copied. The assignment operator is deleted.
1114  */
1115  GrecmutexLock& operator=(const GrecmutexLock&) = delete;
1116 
1117 /**
1118  * This method provides access to the GStaticRecMutex object locked by
1119  * this GrecmutexLock object. It does not throw. It is thread safe.
1120  * @return A pointer to the GStaticRecMutex object.
1121  */
1122  GStaticRecMutex* get() const {return &mutex;}
1123 /**
1124  * This constructor locks the mutex and acquires ownership, and blocks
1125  * if it is already locked until it becomes free, unless the
1126  * constructing thread already holds the lock, in which case it
1127  * increments the lock count and returns immediately. It is not a
1128  * cancellation point. It does not throw.
1129  * @param mutex_ The mutex to be locked.
1130  */
1131  // this is not inline, so we can apply GLIB_VERSION_MIN_REQUIRED
1132  GrecmutexLock(GStaticRecMutex& mutex_);
1133 
1134 /**
1135  * This constructor takes an already locked mutex (say as a result of
1136  * g_static_rec_mutex_trylock()), and takes ownership of it. It is not a
1137  * cancellation point. It does not throw.
1138  * @param mutex_ The mutex to be managed by this object.
1139  * @param tag Pass the Cgu::Thread::locked enum tag to this parameter.
1140  */
1141  GrecmutexLock(GStaticRecMutex& mutex_, Locked tag): mutex(mutex_) {}
1142 
1143 /**
1144  * This class requires initialisation with a GStaticRecMutex. The
1145  * default constructor is deleted.
1146  */
1147  GrecmutexLock() = delete;
1148 
1149 /**
1150  * The destructor unlocks the owned mutex, and either relinquishes
1151  * ownership (if the mutex has not been recursively locked) or
1152  * decrements the lock count (if it has). It is not a cancellation
1153  * point. It does not throw.
1154  */
1155  // this is not inline, so we can apply GLIB_VERSION_MIN_REQUIRED
1156  ~GrecmutexLock();
1157 
1158 /* Only has effect if --with-glib-memory-slices-compat or
1159  * --with-glib-memory-slices-no-compat option picked */
1161 };
1162 
1163 #ifdef CGU_USE_DIAGNOSTIC_PRAGMAS
1164 #pragma GCC diagnostic pop
1165 #endif
1166 
1167 } // namespace Thread
1168 
1169 } // namespace Cgu
1170 
1171 #endif
Cgu::Thread::Cond::get_abs_time
static void get_abs_time(timespec &ts, unsigned int millisec)
Cgu::Thread::Cond::timed_wait
int timed_wait(Mutex &mutex, const timespec &abs_time)
Definition: mutex.h:558
Cgu::Thread::Mutex::TrackLock::unlock
int unlock()
Definition: mutex.h:391
Cgu::Thread::RecMutex::Lock::unlock
int unlock()
Definition: mutex.h:886
Cgu
Definition: application.h:44
Cgu::Thread::RecMutex::TrackLock::~TrackLock
~TrackLock()
Definition: mutex.h:1075
Cgu::Thread::Cond::wait
int wait(Mutex::Lock &lock)
Definition: mutex.h:515
Cgu::Thread::Mutex::TrackLock::trylock
int trylock()
Definition: mutex.h:376
Cgu::Thread::Cond::Cond
Cond()
Cgu::Thread::locked
@ locked
Definition: mutex.h:196
Cgu::Thread::Mutex::TrackLock::TrackLock
TrackLock()=delete
Cgu::Thread::Mutex::Lock::Lock
Lock(Mutex &mutex_, Locked tag)
Definition: mutex.h:293
Cgu::Thread::Cond::have_monotonic_clock
static bool have_monotonic_clock()
Cgu::Thread::RecMutex
A wrapper class for pthread mutexes which provides a recursive mutex.
Definition: mutex.h:672
Cgu::Thread::Cond::broadcast
int broadcast()
Definition: mutex.h:483
Cgu::Thread::GrecmutexLock::GrecmutexLock
GrecmutexLock()=delete
Cgu::Thread::RecMutex::Lock
A scoped locking class for exception safe RecMutex locking.
Definition: mutex.h:802
Cgu::Thread::Mutex::TrackLock::lock
int lock()
Definition: mutex.h:363
Cgu::Thread::Cond::wait
int wait(Mutex::TrackLock &lock)
Definition: mutex.h:522
Cgu::Thread::RecMutex::trylock
int trylock()
Definition: mutex.h:720
Cgu::Thread::Mutex::Lock::~Lock
~Lock()
Definition: mutex.h:305
Cgu::Thread::RecMutex::test_support
static int test_support()
Cgu::Thread::CondError::what
virtual const char * what() const
Definition: mutex.h:67
Cgu::Thread::RecMutex::Lock::operator=
RecMutex::Lock & operator=(const RecMutex::Lock &)=delete
Cgu::Thread::Cond::timed_wait
int timed_wait(Mutex::TrackLock &lock, const timespec &abs_time)
Definition: mutex.h:577
Cgu::Thread::Cond
A wrapper class for pthread condition variables.
Definition: mutex.h:449
Cgu::Thread::RecMutex::TrackLock::TrackLock
TrackLock()=delete
Cgu::Thread::RecMutex::lock
int lock()
Definition: mutex.h:703
Cgu::Thread::Mutex::Lock::trylock
int trylock()
Definition: mutex.h:255
Cgu::Thread::Cond::timed_wait
int timed_wait(Mutex::Lock &lock, const timespec &abs_time)
Definition: mutex.h:568
Cgu::Thread::Cond::signal
int signal()
Definition: mutex.h:472
Cgu::Thread::Mutex::TrackLock::TrackLock
TrackLock(Mutex &mutex_, DeferLock tag)
Definition: mutex.h:424
Cgu::Thread::Mutex::TrackLock::~TrackLock
~TrackLock()
Definition: mutex.h:436
Cgu::Thread::RecMutex::operator=
RecMutex & operator=(const RecMutex &)=delete
Cgu::Thread::Mutex::~Mutex
~Mutex()
Definition: mutex.h:187
Cgu::Thread::Cond::~Cond
~Cond(void)
Definition: mutex.h:633
Cgu::Thread::GrecmutexLock::GrecmutexLock
GrecmutexLock(GStaticRecMutex &mutex_, Locked tag)
Definition: mutex.h:1141
Cgu::Thread::RecMutex::Lock::Lock
Lock(RecMutex &mutex_)
Definition: mutex.h:899
Cgu::Thread::Mutex::TrackLock
A scoped locking class for exception safe Mutex locking which tracks the status of its mutex.
Definition: mutex.h:331
Cgu::Thread::GrecmutexLock::operator=
GrecmutexLock & operator=(const GrecmutexLock &)=delete
Cgu::Thread::Cond::wait
int wait(Mutex &mutex)
Definition: mutex.h:508
Cgu::Thread::RecMutex::TrackLock::trylock
int trylock()
Definition: mutex.h:1005
Cgu::Thread::GrecmutexLock::~GrecmutexLock
~GrecmutexLock()
Cgu::Thread::RecMutex::TrackLock::unlock
int unlock()
Definition: mutex.h:1022
Cgu::Thread::RecMutex::Lock::lock
int lock()
Definition: mutex.h:836
Cgu::Thread::RecMutex::TrackLock
A scoped locking class for exception safe RecMutex locking which tracks the status of its mutex.
Definition: mutex.h:949
Cgu::Thread::RecMutex::TrackLock::TrackLock
TrackLock(RecMutex &mutex_, Locked tag)
Definition: mutex.h:1052
Cgu::Thread::Mutex::Lock::unlock
int unlock()
Definition: mutex.h:277
Cgu::Thread::RecMutex::Lock::trylock
int trylock()
Definition: mutex.h:859
Cgu::Thread::RecMutex::TrackLock::lock
int lock()
Definition: mutex.h:983
Cgu::Thread::Cond::operator=
Cond & operator=(const Cond &)=delete
Cgu::Thread::defer
@ defer
Definition: mutex.h:199
Cgu::Thread::Mutex::TrackLock::TrackLock
TrackLock(Mutex &mutex_, Locked tag)
Definition: mutex.h:415
Cgu::Thread::RecMutex::unlock
int unlock()
Definition: mutex.h:735
Cgu::Thread::Mutex::TrackLock::is_owner
bool is_owner() const
Definition: mutex.h:399
Cgu::Thread::DeferLock
DeferLock
Definition: mutex.h:199
Cgu::Thread::RecMutex::TrackLock::is_owner
bool is_owner() const
Definition: mutex.h:1030
Cgu::Thread::RecMutex::Lock::Lock
Lock(RecMutex &mutex_, Locked tag)
Definition: mutex.h:908
Cgu::Thread::RecMutex::TrackLock::TrackLock
TrackLock(RecMutex &mutex_, DeferLock tag)
Definition: mutex.h:1061
Cgu::Thread::Mutex::lock
int lock()
Definition: mutex.h:147
Cgu::Thread::Mutex::Lock
A scoped locking class for exception safe Mutex locking.
Definition: mutex.h:207
Cgu::Thread::Mutex::Lock::operator=
Mutex::Lock & operator=(const Mutex::Lock &)=delete
Cgu::Thread::GrecmutexLock::get
GStaticRecMutex * get() const
Definition: mutex.h:1122
Cgu::Thread::Mutex::TrackLock::TrackLock
TrackLock(Mutex &mutex_)
Definition: mutex.h:406
CGU_GLIB_MEMORY_SLICES_FUNCS
#define CGU_GLIB_MEMORY_SLICES_FUNCS
Definition: cgu_config.h:84
Cgu::Thread::RecMutex::Lock::Lock
Lock()=delete
Cgu::Thread::GrecmutexLock
A scoped locking class for exception safe locking of GStaticRecMutex objects.
Definition: mutex.h:1103
Cgu::Thread::Locked
Locked
Definition: mutex.h:196
Cgu::Thread::RecMutexError::what
virtual const char * what() const
Definition: mutex.h:86
Cgu::Thread::RecMutex::TrackLock::operator=
RecMutex::TrackLock & operator=(const RecMutex::TrackLock &)=delete
Cgu::Thread::RecMutexError
Definition: mutex.h:85
Cgu::Thread::MutexError::what
virtual const char * what() const
Definition: mutex.h:82
Cgu::Thread::RecMutex::RecMutex
RecMutex()
Cgu::Thread::Mutex::operator=
Mutex & operator=(const Mutex &)=delete
Cgu::Thread::RecMutex::~RecMutex
~RecMutex()
Definition: mutex.h:789
Cgu::Thread::CondError
Definition: mutex.h:66
Cgu::Thread::Mutex::unlock
int unlock()
Definition: mutex.h:170
Cgu::Thread::Mutex::trylock
int trylock()
Definition: mutex.h:157
Cgu::Thread::MutexError
Definition: mutex.h:81
Cgu::Thread::Mutex::Lock::Lock
Lock()=delete
Cgu::Thread::Mutex::Lock::Lock
Lock(Mutex &mutex_)
Definition: mutex.h:284
Cgu::Thread::Mutex::Mutex
Mutex()
Definition: mutex.h:179
Cgu::Thread::Mutex
A wrapper class for pthread mutexes.
Definition: mutex.h:117
cgu_config.h
Cgu::Thread::RecMutex::Lock::~Lock
~Lock()
Definition: mutex.h:921
Cgu::Thread::Mutex::Lock::lock
int lock()
Definition: mutex.h:240
Cgu::Thread::Mutex::TrackLock::operator=
Mutex::TrackLock & operator=(const Mutex::TrackLock &)=delete
Cgu::Thread::RecMutex::TrackLock::TrackLock
TrackLock(RecMutex &mutex_)
Definition: mutex.h:1043