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