c++-gtk-utils: mutex.h Source File

c++-gtk-utils

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

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