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 awoken. It must be called
486  * by the thread which owns the mutex. Re-acquires the mutex when
487  * awoken. It is a cancellation point. This method is cancellation
488  * safe even if the stack does not unwind on cancellation (but if the
489  * stack does not unwind some other way of destroying this object on
490  * cancellation is required, such as by having it allocated on
491  * freestore and deleted in a cancellation clean-up handler). This
492  * 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 after being awoken on waiting, otherwise the pthread
496  * error number.
497  * @note 1. pthread condition variables can, as a matter of design,
498  * awake spontaneously (and Cond::signal() may awaken more than one
499  * thread). Therefore the relevant condition should be tested in a
500  * while loop and not in an if block. 0 will be returned on a
501  * spontaneous awakening.
502  * @note 2. With this library implementation, the only pthread error
503  * numbers which could be returned are EINVAL (if the mutex argument
504  * is not a valid mutex) or EPERM (if the thread calling this method
505  * does not own the mutex).
506  */
507  int wait(Mutex& mutex) {return pthread_cond_wait(&cond, &mutex.pthr_mutex);}
508 
509 /**
510  * Does the same as Cond::wait(Mutex&), except that as a convenience
511  * it will take a Mutex::Lock object handling the Mutex object as an
512  * alternative to passing the Mutex object itself.
513  */
514  int wait(Mutex::Lock& lock) {return wait(lock.mutex);}
515 
516 /**
517  * Does the same as Cond::wait(Mutex&), except that as a convenience
518  * it will take a Mutex::TrackLock object handling the Mutex object as
519  * an alternative to passing the Mutex object itself.
520  */
521  int wait(Mutex::TrackLock& lock) {return wait(lock.mutex);}
522 
523 /**
524  * Waits on this condition variable until awoken (in which case it
525  * re-acquires the mutex), or until the timeout expires (in which case
526  * it re-acquires the mutex and returns with ETIMEDOUT). It must be
527  * called by the thread which owns the mutex. Re-acquires the mutex
528  * when awoken or timing out. It is a cancellation point. This
529  * method is cancellation safe even if the stack does not unwind on
530  * cancellation (but if the stack does not unwind some other way of
531  * destroying this object on cancellation is required, such as by
532  * having it allocated on freestore and deleted in a cancellation
533  * clean-up handler). This method does not throw.
534  * @param mutex The locked mutex associated with the wait which is
535  * re-acquired on being awoken or timing out.
536  * @param abs_time The time at which the wait will unblock if not
537  * previously awoken. A suitable value can be obtained by calling
538  * the get_abs_time() function.
539  * @return 0 after being awoken on waiting, otherwise ETIMEDOUT or
540  * other pthread error number.
541  * @note 1. With this library implementation, apart from ETIMEDOUT,
542  * the only pthread error numbers which could be returned are EINVAL
543  * (if the mutex argument is not a valid mutex or the abs_time
544  * argument does not comprise a valid timespec struct) or EPERM (if
545  * the thread calling this method does not own the mutex).
546  * @note 2. pthread condition variables can, as a matter of design,
547  * awake spontaneously (and Cond::signal() may awaken more than one
548  * thread). Therefore the relevant condition should be tested in a
549  * while loop and not in an if block. 0 will be returned on a
550  * spontaneous awakening.
551  * @note 3. If the system supports monotonic clocks (and this library
552  * is not being cross-compiled onto a different architecture), then
553  * condition variables will use a monotonic clock in
554  * Cond::timed_wait() and Cond::get_abs_time(). This can be tested at
555  * run time with Cond::have_monotonic_clock().
556  */
557  int timed_wait(Mutex& mutex, const timespec& abs_time) {
558  return pthread_cond_timedwait(&cond, &mutex.pthr_mutex, &abs_time);
559  }
560 
561 /**
562  * Does the same as Cond::timed_wait(Mutex&, const timespec&), except
563  * that as a convenience it will take a Mutex::Lock object handling
564  * the Mutex object as an alternative to passing the Mutex object
565  * itself.
566  */
568  const timespec& abs_time) {return timed_wait(lock.mutex, abs_time);}
569 
570 /**
571  * Does the same as Cond::timed_wait(Mutex&, const timespec&), except
572  * that as a convenience it will take a Mutex::TrackLock object
573  * handling the Mutex object as an alternative to passing the Mutex
574  * object itself.
575  */
577  const timespec& abs_time) {return timed_wait(lock.mutex, abs_time);}
578 
579 /**
580  * This is a utility function that inserts into a timespec structure
581  * the current time plus a given number of milliseconds ahead, which
582  * can be applied to a call to Cond::timed_wait(). It does not throw.
583  * It is thread-safe.
584  * @param ts A timespec object into which the result of current time +
585  * millisec will be placed.
586  * @param millisec The number of milliseconds ahead of current time to
587  * which the timespec object will be set.
588  * @note If the system supports monotonic clocks (and this library is
589  * not being cross-compiled onto a different architecture), then
590  * condition variables will use a system monotonic clock in this
591  * method and Cond::timed_wait(). This can be tested at run time with
592  * Cond::have_monotonic_clock().
593  */
594  static void get_abs_time(timespec& ts, unsigned int millisec);
595 
596 /**
597  * Indicates whether the library has been compiled with support for
598  * monotonic clocks in Cond::timed_wait(). Most recent linux and BSD
599  * distributions will support them, and this function would normally
600  * return true unless the library has been cross-compiled from one
601  * platform to a different platform. This function can be tested at
602  * program initialization, and if they are not supported a warning can
603  * be given to the user about the deficiences of using the system
604  * clock for timed events. It does not throw. It is thread safe.
605  * @return true if the library has been compiled with support for
606  * monotonic clocks in Cond::timed_wait(), otherwise false.
607  */
608  static bool have_monotonic_clock();
609 
610 /**
611  * Initialises the pthread condition variable. It is not a
612  * cancellation point.
613  * @exception Cgu::Thread::CondError Throws this exception if
614  * initialization of the condition variable fails. (It is often not
615  * worth checking for CondError, as it means either memory is
616  * exhausted or pthread has run out of other resources to create new
617  * condition variables.)
618  * @note If the system supports monotonic clocks (and this library is
619  * not being cross-compiled onto a different architecture), then
620  * condition variables will use a system monotonic clock in
621  * Cond::timed_wait() and Cond::get_abs_time(). This can be tested at
622  * run time by calling Cond::have_monotonic_clock().
623  */
624  Cond();
625 
626 /**
627  * Destroys the pthread condition variable. It is not a cancellation
628  * point. The destructor does not throw. Destroying a condition
629  * variable on which another thread is currently blocked results in
630  * undefined behavior.
631  */
632  ~Cond(void) {pthread_cond_destroy(&cond);}
633 
634 /* Only has effect if --with-glib-memory-slices-compat or
635  * --with-glib-memory-slices-no-compat option picked */
637 };
638 
639 /**
640  * @class RecMutex mutex.h c++-gtk-utils/mutex.h
641  * @brief A wrapper class for pthread mutexes which provides a
642  * recursive mutex.
643  * @sa Thread::Thread Thread::RecMutex::Lock Thread::RecMutex::TrackLock Thread::Mutex
644  *
645  * This class can be used interchangeably with threads started with
646  * GThread and by this library, as both glib and this library use
647  * pthreads underneath on POSIX and other unix-like OSes. It can also
648  * be used interchangeably with those started by C++11 and with
649  * std::recursive_mutex and similar objects, as in C++11 on unix-like
650  * OSes these facilities will be built on top of pthreads (for which
651  * purpose C++11 provides the std::native_handle_type type and
652  * std::thread::native_handle() function), or if they are not, they
653  * will use the same threading primitives provided by the kernel.
654  *
655  * RecMutex objects can be constructed statically as well as
656  * dynamically and there is no need to call g_thread_init() before
657  * they are constructed, even if glib < 2.32 is used. (If created as
658  * a static object in global scope, it will not be possible to catch
659  * Thread::MutexError or Thread::RecMutexError thrown by its
660  * constructor, but if a static global mutex throws there is nothing
661  * that could be done anyway except abort.)
662  *
663  * See the comments below on the test_support() method of this class,
664  * about how the system's support for native recursive mutexes can be
665  * tested at runtime and when a user program is compiled. If glib >=
666  * 2.32 is installed, it can be assumed that native recursive mutexes
667  * are available, as glib >= 2.32 also uses them.
668  */
669 
670 class RecMutex {
671  pthread_mutex_t pthr_mutex;
672 
673 public:
674  class Lock;
675  class TrackLock;
676 
677 /**
678  * This class cannot be copied. The copy constructor is deleted.
679  */
680  RecMutex(const RecMutex&) = delete;
681 
682 /**
683  * This class cannot be copied. The assignment operator is deleted.
684  */
685  RecMutex& operator=(const RecMutex&) = delete;
686 
687 /**
688  * Locks the mutex and acquires ownership. Blocks if already locked
689  * until it becomes free, unless the calling thread already holds the
690  * lock, in which case it increments the lock count and returns
691  * immediately. It is not a cancellation point. It does not throw.
692  * It is thread safe.
693  * @return 0 if successful, otherwise the pthread mutex error number.
694  * @note With this library implementation, the only pthread error
695  * number which could be returned by this method is EAGAIN, which it
696  * would do if the maximum recursive lock count for this mutex has
697  * been reached. Usually this number is at or around INT_MAX and
698  * hence the return value is usually not worth checking for.
699  */
700  int lock() {return pthread_mutex_lock(&pthr_mutex);}
701 
702 /**
703  * Tries to lock the mutex and acquire ownership, but returns
704  * immediately if it is already locked with value EBUSY unless the
705  * calling thread already holds the lock, in which case it returns
706  * normally and increments the lock count. It is not a cancellation
707  * point. It does not throw. It is thread safe.
708  * @return 0 if successful, otherwise EBUSY or other pthread mutex
709  * error number.
710  * @note With this library implementation, apart from EBUSY, the only
711  * other pthread error number which could be returned by this method
712  * is EAGAIN, which it would do if the maximum recursive lock count
713  * for this mutex has been reached. Usually this number is at or
714  * around INT_MAX and hence an EAGAIN error return value is usually
715  * not worth checking for except during debugging.
716  */
717  int trylock() {return pthread_mutex_trylock(&pthr_mutex);}
718 
719 /**
720  * Unlocks a locked mutex owned by the calling thread and either
721  * relinquishes ownership (if the mutex has not been recursively
722  * locked) or decrements the lock count (if it has). It is not a
723  * cancellation point. It does not throw. It must be called by the
724  * thread which owns the mutex.
725  * @return 0 if successful, otherwise the pthread mutex error number.
726  * @note With this library implementation, the only pthread error
727  * number which could be returned by this method is EPERM because the
728  * calling thread does not own the mutex (however POSIX does not
729  * require that return value in that case and hence the return value
730  * is usually not worth checking for except during debugging).
731  */
732  int unlock() {return pthread_mutex_unlock(&pthr_mutex);}
733 
734 /**
735  * Indicates whether the system supports recursive mutexes. This
736  * method does not throw. It is thread safe.
737  * @return 0 if the system supports recursive mutexes, -1 if it does
738  * not support recursive mutexes and 1 if pthread has run out of
739  * sufficient resources to test this at run time (in which case any
740  * attempt to create mutexes or start threads is likely to fail).
741  * Practically all recent linux and BSD distributions will support
742  * them, and this function would normally return 0. If it does not,
743  * it is still possible to use GStaticRecMutex objects (for which
744  * purpose see Cgu::Thread::GrecmutexLock).
745  *
746  * @note The header file <c++-gtk-utils/cgu_config.h> defines the
747  * symbol CGU_HAVE_RECURSIVE_MUTEX if native recursive mutexes were
748  * found to be supported when this library was compiled. Programs
749  * using this library can therefore test for that symbol with the
750  * pre-processor for conditional compilation purposes (so that the
751  * program can, for example, be compiled to use GStaticRecMutex if
752  * that symbol is not defined). However, if the library was
753  * cross-compiled from one architecture to another, that symbol may
754  * not be defined even though the target architecture does, in fact,
755  * support them at program runtime. In other words, if
756  * CGU_HAVE_RECURSIVE_MUTEX is defined then this method will always
757  * return 0; but in the event of cross-compilation of the library this
758  * method (which provides a separate runtime test) might return 0,
759  * correctly showing support, even when CGU_HAVE_RECURSIVE_MUTEX is
760  * not defined.
761  *
762  * @note If glib >= 2.32 is installed, it can be assumed that native
763  * recursive mutexes are available, as glib >= 2.32 also uses them.
764  */
765  static int test_support();
766 
767 /**
768  * Initialises the pthread mutex. It is not a cancellation point.
769  * @exception Cgu::Thread::RecMutexError Throws this exception if the
770  * system does not support recursive mutexes. (If this has been
771  * checked beforehand, say by calling test_support(), there should be
772  * no need to check for this exception.)
773  * @exception Cgu::Thread::MutexError Throws this exception if
774  * initialization of the mutex fails, except because the system does
775  * not support recursive mutexes. (It is often not worth checking for
776  * MutexError, as it means either memory is exhausted or pthread has
777  * run out of other resources to create new mutexes.)
778  */
779  RecMutex();
780 
781 /**
782  * Destroys the pthread mutex. It is not a cancellation point. It
783  * does not throw. Destroying a mutex which is currently locked
784  * results in undefined behavior.
785  */
786  ~RecMutex() {pthread_mutex_destroy(&pthr_mutex);}
787 
788 /* Only has effect if --with-glib-memory-slices-compat or
789  * --with-glib-memory-slices-no-compat option picked */
791 };
792 
793 /**
794  * @class RecMutex::Lock mutex.h c++-gtk-utils/mutex.h
795  * @brief A scoped locking class for exception safe RecMutex locking.
796  * @sa Thread::RecMutex Thread::RecMutex::TrackLock Thread::Thread
797  */
798 
800  RecMutex& mutex;
801 
802 public:
803 /**
804  * This class cannot be copied. The copy constructor is deleted.
805  */
806  Lock(const RecMutex::Lock&) = delete;
807 
808 /**
809  * This class cannot be copied. The assignment operator is deleted.
810  */
811  RecMutex::Lock& operator=(const RecMutex::Lock&) = delete;
812 
813 /**
814  * This calls RecMutex::lock(), and so locks the mutex and reacquires
815  * ownership. It blocks if the mutex is already locked until the
816  * mutex becomes free, unless the calling thread already holds the
817  * lock, in which case it increments the lock count and returns
818  * immediately. This method should normally only be called if a
819  * previous call has been made to RecMutex::Lock::unlock() (that is,
820  * where the thread owning the RecMutex::Lock object has temporarily
821  * allowed another thread to take the mutex concerned if it is not
822  * recursively locked). It is not a cancellation point. It does not
823  * throw.
824  * @return 0 if successful, otherwise the pthread mutex error number.
825  * @note With this library implementation, the only pthread error
826  * number which could be returned by this method is EAGAIN, which it
827  * would do if the maximum recursive lock count for the particular
828  * mutex in question has been reached. Usually this number is at or
829  * around INT_MAX and hence the return value is usually not worth
830  * checking for except during debugging.
831  * @sa RecMutex::TrackLock.
832  */
833  int lock() {return mutex.lock();}
834 
835 /**
836  * This calls RecMutex::trylock(), and so tries to lock the mutex and
837  * reacquire ownership, but returns immediately if it is already
838  * locked with value EBUSY unless the calling thread already holds the
839  * lock, in which case it returns normally and increments the lock
840  * count. This method should normally only be called if a previous
841  * call has been made to RecMutex::Lock::unlock() (that is, where the
842  * thread owning the RecMutex::Lock object has temporarily allowed
843  * another thread to take the mutex concerned if it is not recursively
844  * locked). It is not a cancellation point. It does not throw.
845  * @return 0 if successful, otherwise EBUSY or other pthread mutex
846  * error number.
847  * @note With this library implementation, apart from EBUSY, the only
848  * other pthread error number which could be returned by this method
849  * is EAGAIN, which it would do if the maximum recursive lock count
850  * for the particular mutex in question has been reached. Usually
851  * this number is at or around INT_MAX and hence an EAGAIN error
852  * return value is usually not worth checking for except during
853  * debugging.
854  * @sa RecMutex::TrackLock.
855  */
856  int trylock() {return mutex.trylock();}
857 
858 /**
859  * This calls RecMutex::unlock() and so unlocks a locked mutex owned
860  * by the calling thread, so temporarily allowing another thread to
861  * take the mutex if the mutex has not been recursively locked, or if
862  * it has been recursively locked decrements the lock count, so
863  * temporarily relinquishing ownership. This method should normally
864  * only be called if it is to be followed by a call to
865  * RecMutex::Lock::lock() or a successful call to
866  * RecMutex::Lock::trylock() before the RecMutex::Lock object
867  * concerned goes out of scope (otherwise RecMutex::Lock's destructor
868  * will attempt to decrement the lock count of a mutex which already
869  * has a lock count of 0 or which another thread has by then taken
870  * ownership or leave the lock count in an unbalanced condition -
871  * RecMutex::Lock objects do not maintain state). See
872  * RecMutex::TrackLock::unlock() for a safe version of this method.
873  * It is not a cancellation point. It does not throw.
874  * @return 0 if successful, otherwise the pthread mutex error number.
875  * @note With this library implementation, the only pthread error
876  * number which could be returned by this method is EPERM because the
877  * calling thread does not own the particular mutex in question
878  * (however POSIX does not require that return value in that case and
879  * hence the return value is usually not worth checking for except
880  * during debugging).
881  * @sa RecMutex::TrackLock.
882  */
883  int unlock() {return mutex.unlock();}
884 
885 /**
886  * This constructor locks the mutex passed to it. See
887  * RecMutex::lock() for a description of the outcomes. It is not a
888  * cancellation point.
889  * @param mutex_ The mutex to be locked.
890  * @exception Cgu::Thread::RecMutexError Throws this exception if
891  * initialization of the mutex fails because the maximum recursive
892  * lock count for the particular mutex in question has been reached.
893  * Usually this number is at or around INT_MAX so it is not usually
894  * useful to check for it except during debugging.
895  */
896  Lock(RecMutex& mutex_): mutex(mutex_) {if (mutex.lock()) throw RecMutexError();}
897 
898 /**
899  * This constructor takes an already locked mutex (say as a result of
900  * RecMutex::trylock()), and takes ownership of it. It is not a
901  * cancellation point. It does not throw.
902  * @param mutex_ The mutex to be managed by this object.
903  * @param tag Pass the Cgu::Thread::locked enum tag to this parameter.
904  */
905  Lock(RecMutex& mutex_, Locked tag): mutex(mutex_) {}
906 
907 /**
908  * This class requires initialisation with a RecMutex. The default
909  * constructor is deleted.
910  */
911  Lock() = delete;
912 
913 /**
914  * The destructor unlocks the owned mutex. See RecMutex::unlock() for
915  * a description of the outcomes. It is not a cancellation point. It
916  * does not throw.
917  */
918  ~Lock() {mutex.unlock();}
919 
920 /* Only has effect if --with-glib-memory-slices-compat or
921  * --with-glib-memory-slices-no-compat option picked */
923 };
924 
925 /**
926  * @class RecMutex::TrackLock mutex.h c++-gtk-utils/mutex.h
927  * @brief A scoped locking class for exception safe RecMutex locking
928  * which tracks the status of its mutex.
929  * @sa Thread::RecMutex Thread::RecMutex::Lock Thread::Thread
930  *
931  * This class is similar to a RecMutex::Lock object, except that it
932  * tracks whether the mutex it manages is locked by the thread
933  * creating the RecMutex::TrackLock object with respect to the
934  * particular locking operation to be governed by the object (provided
935  * that, while the RecMutex::TrackLock object exists, the thread
936  * creating it only accesses the mutex with respect that particular
937  * operation through that object). This enables
938  * RecMutex::TrackLock::unlock() to be used without it being followed
939  * later by a call to RecMutex::TrackLock::lock() or a successful call
940  * to RecMutex::TrackLock::trylock(), and also permits locking to be
941  * deferred until after construction of the lock object. Note that
942  * only one thread may call the methods of any one RecMutex::TrackLock
943  * object, including causing its destructor to be invoked.
944  */
945 
947  RecMutex& mutex;
948  bool owner;
949 
950 public:
951 
952 /**
953  * This class cannot be copied. The copy constructor is deleted.
954  */
955  TrackLock(const RecMutex::TrackLock&) = delete;
956 
957 /**
958  * This class cannot be copied. The assignment operator is deleted.
959  */
961 
962 /**
963  * This calls RecMutex::lock(), and so locks the mutex and acquires
964  * ownership. It blocks if the mutex is already locked until the
965  * mutex becomes free, unless the calling thread already holds the
966  * lock, in which case it increments the lock count and returns
967  * immediately. This method should normally only be called if a
968  * previous call has been made to RecMutex::TrackLock::unlock() or
969  * this RecMutex::TrackLock object has been constructed with the
970  * Thread::defer enum tag. It is not a cancellation point. It does
971  * not throw.
972  * @return 0 if successful, otherwise the pthread mutex error number.
973  * @note With this library implementation, the only pthread error
974  * number which could be returned by this method is EAGAIN, which it
975  * would do if the maximum recursive lock count for the particular
976  * mutex in question has been reached. Usually this number is at or
977  * around INT_MAX and hence the return value is usually not worth
978  * checking for except during debugging.
979  */
980  int lock() {int ret = mutex.lock(); if (!owner) owner = !ret; return ret;}
981 
982 /**
983  * This calls RecMutex::trylock(), and so tries to lock the mutex and
984  * acquire ownership, but returns immediately if it is already locked
985  * with value EBUSY unless the calling thread already holds the lock,
986  * in which case it returns normally and increments the lock count.
987  * This method should normally only be called if a previous call has
988  * been made to RecMutex::TrackLock::unlock() or this
989  * RecMutex::TrackLock object has been constructed with the
990  * Thread::defer enum tag. It is not a cancellation point. It does
991  * not throw.
992  * @return 0 if successful, otherwise EBUSY or other pthread mutex
993  * error number.
994  * @note With this library implementation, apart from EBUSY, the only
995  * other pthread error number which could be returned by this method
996  * is EAGAIN, which it would do if the maximum recursive lock count
997  * for the particular mutex in question has been reached. Usually
998  * this number is at or around INT_MAX and hence an EAGAIN error
999  * return value is usually not worth checking for except during
1000  * debugging.
1001  */
1002  int trylock() {int ret = mutex.trylock(); if (!owner) owner = !ret; return ret;}
1003 
1004 /**
1005  * This calls RecMutex::unlock(), and so unlocks a locked mutex owned
1006  * by the calling thread, or decrements the lock count (if it has been
1007  * recursively locked). It will cause is_owner() to return false
1008  * unless a subsequent call is made to lock() or a subsequent
1009  * successful call is made to trylock(). It is not a cancellation
1010  * point. It does not throw.
1011  * @return 0 if successful, otherwise the pthread mutex error number.
1012  * @note With this library implementation, the only pthread error
1013  * number which could be returned by this method is EPERM because the
1014  * calling thread does not own the particular mutex in question
1015  * (however POSIX does not require that return value in that case and
1016  * hence the return value is usually not worth checking for except
1017  * during debugging).
1018  */
1019  int unlock() {int ret = mutex.unlock(); if (owner) owner = ret; return ret;}
1020 
1021 /**
1022  * Indicates whether the mutex managed by this Mutex::TrackLock object
1023  * is locked by it (whether originally or recursively) and so owned by
1024  * it.
1025  * @return true if the mutex is owned by this object, otherwise false.
1026  */
1027  bool is_owner() const {return owner;}
1028 
1029 /**
1030  * This constructor locks the mutex passed to it. See
1031  * RecMutex::lock() for a description of the outcomes. It is not a
1032  * cancellation point. It does not throw.
1033  * @param mutex_ The mutex to be locked.
1034  * @exception Cgu::Thread::RecMutexError Throws this exception if
1035  * initialization of the mutex fails because the maximum recursive
1036  * lock count for the particular mutex in question has been reached.
1037  * Usually this number is at or around INT_MAX so it is not usually
1038  * useful to check for it except during debugging.
1039  */
1040  TrackLock(RecMutex& mutex_): mutex(mutex_), owner(true) {if (mutex.lock()) throw RecMutexError();}
1041 
1042 /**
1043  * This constructor takes an already locked mutex (say as a result of
1044  * RecMutex::trylock()), and takes ownership of it. It is not a
1045  * cancellation point. It does not throw.
1046  * @param mutex_ The mutex to be managed by this object.
1047  * @param tag Pass the Cgu::Thread::locked enum tag to this parameter.
1048  */
1049  TrackLock(RecMutex& mutex_, Locked tag): mutex(mutex_), owner(true) {}
1050 
1051 /**
1052  * This constructor defers locking of the mutex (and so taking
1053  * ownership of it) until an explicit call to lock() or trylock() is
1054  * made. It is not a cancellation point. It does not throw.
1055  * @param mutex_ The mutex to be managed by this object.
1056  * @param tag Pass the Cgu::Thread::defer enum tag to this parameter.
1057  */
1058  TrackLock(RecMutex& mutex_, DeferLock tag): mutex(mutex_), owner(false) {}
1059 
1060 /**
1061  * This class requires initialisation with a RecMutex. The default
1062  * constructor is deleted.
1063  */
1064  TrackLock() = delete;
1065 
1066 /**
1067  * The destructor unlocks the managed mutex if it is owned by this
1068  * RecMutex::TrackLock object. See RecMutex::unlock() for a
1069  * description of the outcomes if it is so owned. It is not a
1070  * cancellation point. It does not throw.
1071  */
1072  ~TrackLock() {if (owner) mutex.unlock();}
1073 
1074 /* Only has effect if --with-glib-memory-slices-compat or
1075  * --with-glib-memory-slices-no-compat option picked */
1077 };
1078 
1079 /**
1080  * @class GrecmutexLock mutex.h c++-gtk-utils/mutex.h
1081  * @brief A scoped locking class for exception safe locking of
1082  * GStaticRecMutex objects.
1083  * @details This class is mainly intended for use where the native
1084  * pthreads implementation does not support recursive mutexes so
1085  * Cgu::Thread::RecMutex and Cgu::Thread::RecMutex::Lock cannot be
1086  * used.
1087  *
1088  * It should be noted that this class is for use with GStaticRecMutex
1089  * objects, and not the GRecMutex objects available in glib from glib
1090  * version 2.32. If glib >= 2.32 is installed, it can be assumed that
1091  * native recursive mutexes and so Cgu::Thread::RecMutex are
1092  * available, as glib >= 2.32 also uses native recursive mutexes.
1093  */
1095  GStaticRecMutex& mutex;
1096 public:
1097 
1098 /**
1099  * This class cannot be copied. The copy constructor is deleted.
1100  */
1101  GrecmutexLock(const GrecmutexLock&) = delete;
1102 
1103 /**
1104  * This class cannot be copied. The assignment operator is deleted.
1105  */
1106  GrecmutexLock& operator=(const GrecmutexLock&) = delete;
1107 
1108 /**
1109  * This method provides access to the GStaticRecMutex object locked by
1110  * this GrecmutexLock object. It does not throw. It is thread safe.
1111  * @return A pointer to the GStaticRecMutex object.
1112  */
1113  GStaticRecMutex* get() const {return &mutex;}
1114 /**
1115  * This constructor locks the mutex and acquires ownership, and blocks
1116  * if it is already locked until it becomes free, unless the
1117  * constructing thread already holds the lock, in which case it
1118  * increments the lock count and returns immediately. It is not a
1119  * cancellation point. It does not throw.
1120  * @param mutex_ The mutex to be locked.
1121  */
1122  // this is not inline, so we can apply GLIB_VERSION_MIN_REQUIRED
1123  GrecmutexLock(GStaticRecMutex& mutex_);
1124 
1125 /**
1126  * This constructor takes an already locked mutex (say as a result of
1127  * g_static_rec_mutex_trylock()), and takes ownership of it. It is not a
1128  * cancellation point. It does not throw.
1129  * @param mutex_ The mutex to be managed by this object.
1130  * @param tag Pass the Cgu::Thread::locked enum tag to this parameter.
1131  */
1132  GrecmutexLock(GStaticRecMutex& mutex_, Locked tag): mutex(mutex_) {}
1133 
1134 /**
1135  * This class requires initialisation with a GStaticRecMutex. The
1136  * default constructor is deleted.
1137  */
1138  GrecmutexLock() = delete;
1139 
1140 /**
1141  * The destructor unlocks the owned mutex, and either relinquishes
1142  * ownership (if the mutex has not been recursively locked) or
1143  * decrements the lock count (if it has). It is not a cancellation
1144  * point. It does not throw.
1145  */
1146  // this is not inline, so we can apply GLIB_VERSION_MIN_REQUIRED
1147  ~GrecmutexLock();
1148 
1149 /* Only has effect if --with-glib-memory-slices-compat or
1150  * --with-glib-memory-slices-no-compat option picked */
1152 };
1153 
1154 } // namespace Thread
1155 
1156 } // namespace Cgu
1157 
1158 #endif