c++-gtk-utils
thread.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 */
24 
25 #ifndef CGU_THREAD_H
26 #define CGU_THREAD_H
27 
28 #include <memory> // for std::unique_ptr or std::auto_ptr
29 #include <utility> // for std::move
30 
31 #include <pthread.h>
32 
33 #include <c++-gtk-utils/callback.h>
34 #include <c++-gtk-utils/mutex.h>
36 
37 namespace Cgu {
38 
39 namespace Thread {
40 
41 /**
42  * @class Cgu::Thread::Thread thread.h c++-gtk-utils/thread.h
43  * @brief A class representing a pthread thread.
44  * @sa Thread::Mutex Thread::Mutex::Lock Thread::Cond Thread::Future Thread::JoinableHandle
45  *
46  * The Thread class encapsulates a pthread thread. It can start, join
47  * and cancel a thread.
48  *
49  * The Thread class, and the associated CancelBlock class, can be used
50  * interchangeably with (and mixed with) GThread objects and
51  * functions, and GMutex, GStaticMutex, GStaticRecMutex and GCond, as
52  * they all use pthreads underneath on POSIX and other unix-like OSes.
53  * In addition it can be used with threads started with the C++11
54  * threading facilities, as in C++11 on unix-like OSes these
55  * facilities will be built on top of pthreads (for which purpose
56  * C++11 provides the std::native_handle_type type and
57  * std::thread::native_handle() function). Even where they are not,
58  * they will use the same threading primitives provided by the kernel.
59  *
60  * @anchor ThreadsAnchor
61  * @b c++-gtk-utils @b library @b and @b C++11 @b threads
62  *
63  * As mentioned above, the thread facilities provided by this library
64  * can be freely interchanged with the threading facilities provided
65  * by C++11.
66  *
67  * The main features available from this library and not C++11 are
68  * thread cancellation and the associated Cgu::Thread::CancelBlock
69  * class, and the Cgu::Thread::JoinableHandle class for scoped
70  * joinable thread handling.
71  *
72  * C++11 does not provide thread cancellation or interruption support,
73  * and C++ will never be able to do so on a complete basis because to
74  * do so requires support from the underlying OS, which therefore
75  * makes it platform specific (in this case, POSIX specific):
76  * cancellation is only of limited use if it cannot reliably interrupt
77  * blocking system calls. The POSIX specification sets out the
78  * interruptible cancellation points in System Interfaces, section
79  * 2.9.5, Cancellation Points, and in effect specifies all the system
80  * calls which can block as cancellation points.
81  *
82  * Whether, in C++ programs, destructors of local objects in the
83  * cancelled thread are called is also system specific and is not
84  * specified by POSIX. Most modern commercial unixes, and recent
85  * linux/BSD distributions based on NPTL (in the case of Linux, those
86  * based on 2.6/3.* kernels), will unwind the stack and call
87  * destructors on thread cancellation by means of a pseudo-exception,
88  * but older distributions relying on the former linuxthreads
89  * implementation will not. Therefore for maximum portability
90  * cancellation would only be used where there are plain data
91  * structures/built-in types in existence in local scope when it
92  * occurs, and if there is anything in free store to be released some
93  * clean-ups would be implemented with
94  * pthread_cleanup_push()/pthread_cleanup_pop(). This should be
95  * controlled with pthread_setcancelstate() and/or the CancelBlock
96  * class to choose the cancellation point.
97  *
98  * One of the (perhaps odd) features of C++11 threads is that if the
99  * destructor of a std::thread object is called which represents a
100  * joinable thread which has not been detach()ed or join()ed, the
101  * whole program is terminated with a call to std::terminate(), which
102  * makes it difficult to use in the presence of exceptions. Often
103  * what is wanted however is for join() to be called on a joinable
104  * thread where the associated thread object goes out of scope, or
105  * (provided it is done carefully and knowingly) for detach() to be
106  * called. The Cgu::Thread::JoinableHandle class can be used where
107  * either of these two is the appropriate response to this situation.
108  *
109  * In addition, the c++-gtk-utils library provides the following which
110  * are not present in C++11: a guaranteed monotonic clock on timed
111  * condition variable waits where the operating system supports them;
112  * read-write locks; and a Cgu::Thread::Future object which is more
113  * intuitive to use than C++11 futures and features a built in
114  * Cgu::SafeEmitter object which emits when the particular task has
115  * completed, and (since version 2.0.2) has associated
116  * Cgu::Thread::Future::when() methods for passing the result to a
117  * glib main loop.
118  *
119  * @b c++-gtk-utils @b library @b and @b gthreads
120  *
121  * As mentioned above, the thread facilities provided by this library
122  * can be freely interchanged with the threading facilities provided
123  * by glib.
124  *
125  * The main features available with this thread implementation and not
126  * GThreads are thread cancellation, the mutex scoped locking classes
127  * Cgu::Thread::Mutex::Lock and Cgu::Thread::RecMutex::Lock, the
128  * joinable thread scoped management class Cgu::Thread::JoinableHandle
129  * and the Cgu::Thread::Future class (abstracting thread functions
130  * which provide a result).
131  *
132  * There is no need from the perspective of this class to call
133  * g_thread_init() before Cgu::Thread::Thread::start() is called, but
134  * but prior to glib version 2.32 glib itself is not thread-safe
135  * without g_thread_init(), so where this class is used with glib <
136  * 2.32, g_thread_init() should be called at program initialization.
137  *
138  * See @ref Threading for particulars about GTK+ thread safety.
139  */
140 
141 
142 class Thread {
143  pthread_t thread;
144  // private constructor - this class can only be created with Thread::start
145  Thread() {}
146 public:
147 /**
148  * This class cannot be copied: it is intended to be held by
149  * std::unique_ptr. The copy constructor is deleted.
150  */
151  Thread(const Thread&) = delete;
152 
153 /**
154  * This class cannot be copied: it is intended to be held by
155  * std::unique_ptr. The assignment operator is deleted.
156  */
157  Thread& operator=(const Thread&) = delete;
158 
159 /**
160  * Cancels the thread represented by this Thread object. It can be
161  * called by any thread. The effect is undefined if the thread
162  * represented by this Thread object has both (a) already terminated
163  * and (b) been detached or had a call to join() made for it.
164  * Accordingly, if the user is not able to establish from the program
165  * logic whether the thread has terminated, the thread must be created
166  * as joinable and cancel() must not be called after a call to
167  * detach() has been made or a call to join() has returned. A
168  * Thread::JoinableHandle object can used to ensure this. It does not
169  * throw.
170  * @note Use this method with care - sometimes its use is unavoidable
171  * but destructors for local objects may not be called if a thread
172  * exits by virtue of a call to cancel() (that depends on the
173  * implementation). Most modern commercial unixes, and recent
174  * linux/BSD distributions based on NPTL, will unwind the stack and
175  * call destructors on thread cancellation by means of a
176  * pseudo-exception, but older distributions relying on the former
177  * linuxthreads implementation will not. Therefore for maximum
178  * portability only have plain data structures/built-in types in
179  * existence in local scope when it occurs and if there is anything in
180  * free store to be released implement some clean-ups with
181  * pthread_cleanup_push()/pthread_cleanup_pop(). This should be
182  * controlled with pthread_setcancelstate() and/or the CancelBlock
183  * class to choose the cancellation point.
184  * @sa Cgu::Thread::Exit
185  */
186  void cancel() {pthread_cancel(thread);}
187 
188 /**
189  * Joins the thread represented by this Thread object (that is, waits
190  * for it to terminate). It can be called by any thread other than
191  * the one represented by this Thread object. The result is undefined
192  * if the thread is or was detached or join() has already been called
193  * for the thread (a Thread::JoinableHandle object will however give a
194  * defined result in such cases for threads originally started as
195  * joinable). It does not throw.
196  */
197  void join() {pthread_join(thread, 0);}
198 
199 /**
200  * Detaches the thread represented by this Thread object where it is
201  * joinable, so as to make it unjoinable. The effect is unspecified
202  * if the thread is already unjoinable (a Thread::JoinableHandle
203  * object will however give a defined result in such cases for threads
204  * originally started as joinable). It does not throw.
205  */
206  void detach() {pthread_detach(thread);}
207 
208 /**
209  * Specifies whether the calling thread is the same thread as is
210  * represented by this Thread object. The effect is undefined if the
211  * thread represented by this Thread object has both (a) already
212  * terminated and (b) been detached or had a call to join() made for
213  * it. Accordingly, if the user is not able to establish from the
214  * program logic whether the thread has terminated, the thread must be
215  * created as joinable and is_caller() must not be called after a call
216  * to detach() has been made or a call to join() has returned. A
217  * Thread::JoinableHandle object can used to ensure this. This method
218  * does not throw.
219  * @return Returns true if the caller is in the thread represented by
220  * this Thread object.
221  */
222  bool is_caller() {return pthread_equal(thread, pthread_self());}
223 
224 /**
225  * Starts a new thread. It can be called by any thread.
226  * @param cb A callback object (created by Callback::make())
227  * encapsulating the function to be executed by the new thread. The
228  * Thread object returned by this function will take ownership of the
229  * callback: it will automatically be deleted either by the new thread
230  * when it has finished with it, or by this method in the calling
231  * thread if the attempt to start a new thread fails (including if
232  * std::bad_alloc is thrown).
233  * @param joinable Whether the join() method may be called in relation
234  * to the new thread.
235  * @return A Thread object representing the new thread which has been
236  * started, held by a std::unique_ptr object as it has single
237  * ownership semantics. The std::unique_ptr object will be empty
238  * (that is std::unique_ptr<Cgu::Thread::Thread>::get() will return 0)
239  * if the thread did not start correctly, which would mean that memory
240  * is exhausted, the pthread thread limit has been reached or pthread
241  * has run out of other resources to start new threads.
242  * @exception std::bad_alloc This method might throw std::bad_alloc if
243  * memory is exhausted and the system throws in that case. (This
244  * exception will not be thrown if the library has been installed
245  * using the --with-glib-memory-slices-no-compat configuration option:
246  * instead glib will terminate the program if it is unable to obtain
247  * memory from the operating system.)
248  * @note 1. The thread will keep running even if the return value of
249  * start() goes out of scope (but it will no longer be possible to
250  * call any of the methods in this class for it, which is fine if the
251  * thread is not started as joinable and it is not intended to cancel
252  * it).
253  * @note 2. If the thread is started with the joinable attribute, the
254  * user must subsequently either call the join() or the detach()
255  * method, as otherwise a resource leak may occur (the destructor of
256  * this class does not call detach() automatically). Alternatively,
257  * the return value of this method can be passed to a
258  * Thread::JoinableHandle object which will do this automatically in
259  * the Thread::JoinableHandle object's destructor.
260  * @note 3. Any Thread::Exit exception thrown from the function
261  * executed by the new thread will be caught and consumed. The thread
262  * will safely terminate and unwind the stack in so doing.
263  * @note 4. If any uncaught exception other than Thread::Exit is
264  * allowed to propagate from the initial function executed by the new
265  * thread, the exception is not consumed (NPTL's forced stack
266  * unwinding on cancellation does not permit catching with an ellipsis
267  * argument without rethrowing, and even if it did permit it, the
268  * result would be an unreported error). The C++11 standard requires
269  * std::terminate() to be called in such a case and so the entire
270  * program terminated. Accordingly, a user must make sure that no
271  * exceptions, other than Thread::Exit or any cancellation
272  * pseudo-exception, can propagate from the initial function executed
273  * by the new thread.
274  * @note 5. If the library is compiled using the --with-auto-ptr
275  * configuration option, then this function will return a
276  * Thread::Thread object by std::auto_ptr instead of std::unique_ptr
277  * in order to retain compatibility with the 1.2 series of the
278  * library.
279  */
280 #ifdef CGU_USE_AUTO_PTR
281  static std::auto_ptr<Cgu::Thread::Thread> start(const Cgu::Callback::Callback* cb,
282  bool joinable);
283 #else
284  static std::unique_ptr<Cgu::Thread::Thread> start(const Cgu::Callback::Callback* cb,
285  bool joinable);
286 #endif
287 
288 #ifdef CGU_USE_GLIB_MEMORY_SLICES_NO_COMPAT
290 #endif
291 };
292 
293 /**
294  * @class Cgu::Thread::JoinableHandle thread.h c++-gtk-utils/thread.h
295  * @brief A class wrapping a Thread::Thread object representing a
296  * joinable thread.
297  * @sa Thread::Thread Thread::Future
298  *
299  * This class enables a joinable thread to be made more easily
300  * exception safe. It can also be used to provide that a joinable
301  * thread is not detached or joined while other methods dependent on
302  * that might still be called, and to provide a defined result where
303  * there are multiple calls to join() and/or detach(). When it is
304  * destroyed, it will either detach or join the thread represented by
305  * the wrapped Thread::Thread object unless it has previously been
306  * detached or joined using the detach() or join() methods, so
307  * avoiding thread resource leaks. Whether it will detach() or join()
308  * on destruction depends on the Thread::JoinableHandle::Action
309  * argument passed to the
310  * Thread::JoinableHandle::JoinableHandle(std::unique_ptr<Thread::Thread>,
311  * Action) constructor.
312  *
313  * Passing Thread::JoinableHandle::detach_on_exit to that argument is
314  * not always the correct choice where the thread callback has been
315  * bound to a reference argument in local scope and an exception might
316  * be thrown, because the thread will keep running after the
317  * Thread::JoinableHandle object and other local variables have
318  * (because of the exception) gone out of scope. Consider the
319  * following trivial parallelized calculation example:
320  *
321  * @code
322  * std::vector<int> get_readings();
323  * void get_mean(const std::vector<int>& v, int& result);
324  * void get_std_deviation(const std::vector<int>& v, int& result); // might throw
325  * void show_result(int mean, int deviation);
326  *
327  * using namespace Cgu;
328  * void do_calc() {
329  * int i, j;
330  * std::vector<int> v = get_readings();
331  * // with bound reference arguments, Callback::make() requires explicit type instantation
332  * std::unique_ptr<Thread::Thread> t =
333  * Thread::Thread::start(Callback::make<const std::vector<int>&, int&>(&get_mean, v, i), true);
334  * if (t.get()) { // checks whether thread started correctly
335  * get_std_deviation(v, j);
336  * t->join();
337  * show_result(i, j);
338  * }
339  * }
340  * @endcode
341  *
342  * If get_std_deviation() throws, as well as there being a potential
343  * thread resource leak by virtue of no join being made, the thread
344  * executing get_mean() will continue running and attempt to access
345  * variable v, and put its result in variable i, which may by then
346  * both be out of scope. To deal with such a case, the thread could
347  * be wrapped in a Thread::JoinableHandle object which joins on exit
348  * rather than detaches, for example:
349  *
350  * @code
351  * ...
352  * using namespace Cgu;
353  * void do_calc() {
354  * int i, j;
355  * std::vector<int> v = get_readings();
356  * // with reference arguments, Callback::make() requires explicit type instantation
357  * Thread::JoinableHandle t(Thread::Thread::start(Callback::make<const std::vector<int>&, int&>(&get_mean, v, i), true),
358  * Thread::JoinableHandle::join_on_exit);
359  * if (t.is_managing()) { // checks whether thread started correctly
360  * get_std_deviation(v, j);
361  * t.join();
362  * show_result(i, j);
363  * }
364  * }
365  * @endcode
366  *
367  * Better still, however, would be to use Cgu::Thread::Future in this
368  * kind of usage, namely a usage where a worker thread is intended to
369  * provide a result for inspection.
370  *
371  * @note These examples assume that the std::vector library
372  * implementation permits concurrent reads of a vector object by
373  * different threads. Whether that is the case depends on the
374  * documentation of the library concerned (if designed for a
375  * multi-threaded environment, most will permit this).
376  */
378 public:
380 
381 private:
382  Mutex mutex; // make this the first member so the constructors are strongly exception safe
383  Action action;
384  bool detached;
385  std::unique_ptr<Cgu::Thread::Thread> thread;
386 
387 public:
388 /**
389  * Cancels the thread represented by the wrapped Thread::Thread
390  * object. It can be called by any thread. The effect is undefined
391  * if when called the thread represented by the wrapped Thread::Thread
392  * object has both (a) already terminated and (b) had a call to join()
393  * or detach() made for it. Accordingly, if the user is not able to
394  * establish from the program logic whether the thread has terminated,
395  * cancel() must not be called after a call to detach() has been made
396  * or a call to join() has returned: this can be ensured by only
397  * detaching or joining via this object's destructor (that is, by not
398  * using the explicit detach() and join() methods). This method does
399  * not throw.
400  * @note Use this method with care - see Thread::cancel() for further
401  * information.
402  */
403  void cancel();
404 
405 /**
406  * Joins the thread represented by the wrapped Thread::Thread object
407  * (that is, waits for it to terminate), unless the detach() or join()
408  * method has previously been called in which case this call does
409  * nothing. It can be called by any thread other than the one
410  * represented by the wrapped Thread::Thread object, but only one
411  * thread can wait on it: if one thread (thread A) calls it while
412  * another thread (thread B) is already blocking on it, thread A's
413  * call to this method will return immediately and return false. It
414  * does not throw.
415  * @return true if a successful join() has been accomplished (that is,
416  * detach() or join() have not previously been called), otherwise
417  * false.
418  */
419  bool join();
420 
421 /**
422  * Detaches the thread represented by this Thread::Thread object, so
423  * as to make it unjoinable, unless the detach() or join() method has
424  * previously been called in which case this call does nothing. It
425  * does not throw.
426  */
427  void detach();
428 
429 /**
430  * Specifies whether the calling thread is the same thread as is
431  * represented by the wrapped Thread::Thread object. It can be called
432  * by any thread. The effect is undefined if the thread represented
433  * by the wrapped Thread::Thread object has both (a) already
434  * terminated and (b) had a call to join() or detach() made for it.
435  * Accordingly, if the user is not able to establish from the program
436  * logic whether the thread has terminated, is_caller() must not be
437  * called after a call to detach() has been made or a call to join()
438  * has returned: this can be ensured by only detaching or joining via
439  * this object's destructor (that is, by not using the explicit
440  * detach() and join() methods). This method does not throw.
441  * @return Returns true if the caller is in the thread represented by
442  * the wrapped Thread::Thread object. If not, or this JoinableHandle
443  * does not wrap any Thread object, then returns false.
444  */
445  bool is_caller();
446 
447 /**
448  * Specifies whether this JoinableHandle object has been initialized
449  * with a Thread::Thread object representing a correctly started
450  * thread in respect of which neither JoinableHandle::detach() nor
451  * JoinableHandle::join() has been called. It can be called by any
452  * thread. It is principally intended to enable the constructor
453  * taking a std::unique_ptr<Cgu::Thread::Thread> object to be directly
454  * initialized by a call to Thread::Thread::start(), by providing a
455  * means for the thread calling Thread::Thread::start() to check
456  * afterwards that the new thread did, in fact, start correctly. Note
457  * that this method will return true even after the thread has
458  * finished, provided neither the join() nor detach() method has been
459  * called.
460  * @return Returns true if this object has been initialized by a
461  * Thread::Thread object representing a correctly started thread in
462  * respect of which neither JoinableHandle::detach() nor
463  * JoinableHandle::join() has been called, otherwise false.
464  */
465  bool is_managing();
466 
467 /**
468  * Moves one JoinableHandle object to another JoinableHandle object.
469  * This is a move operation which transfers ownership to the assignee,
470  * as the handles store their Thread::Thread object by
471  * std::unique_ptr<>. Any existing thread managed by the assignee
472  * prior to the move will be detached if it has not already been
473  * detached or joined. This method will not throw.
474  * @param h The assignor/movant, which will cease to hold a valid
475  * Thread::Thread object after the move has taken place.
476  * @return A reference to the assignee JoinableHandle object after
477  * assignment.
478  * @note 1. This method is thread safe as regards the assignee (the
479  * object assigned to), but no synchronization is carried out with
480  * respect to the rvalue assignor/movant. This is because temporaries
481  * are only visible and accessible in the thread carrying out the move
482  * operation and synchronization for them would represent pointless
483  * overhead. In a case where the user uses std::move to force a move
484  * from a named object, and that named object's lifetime is managed by
485  * (or the object is otherwise accessed by) a different thread than
486  * the one making the move, the user must carry out her own
487  * synchronization with respect to that different thread, as the named
488  * object will be mutated by the move.
489  * @note 2. If the library is compiled using the --with-auto-ptr
490  * configuration option, then this operator's signature is
491  * JoinableHandle& operator=(JoinableHandle& h) in order to retain
492  * compatibility with the 1.2 series of the library.
493  */
494 #ifdef CGU_USE_AUTO_PTR
496 #else
498 #endif
499 
500 /**
501  * This constructor initializes a new JoinableHandle object with a
502  * std::unique_ptr<Thread::Thread> object, as provided by
503  * Thread::Thread::start(). This is a move operation which transfers
504  * ownership to the new object.
505  * @param thr The initializing Thread::Thread object (which must have
506  * been created as joinable) passed by a std::unique_ptr smart
507  * pointer. This is a move operation.
508  * @param act Either Thread::JoinableHandle::detach_on_exit (which
509  * will cause the destructor to detach the thread if it has not
510  * previously been detached or joined) or
511  * Thread::JoinableHandle::join_on_exit (which will cause the
512  * destructor to join the thread if it has not previously been
513  * detached or joined).
514  * @exception Cgu::Thread::MutexError Throws this exception if
515  * initialization of the internal mutex fails. The constructor is
516  * strongly exception safe: if Cgu::Thread::MutexError is thrown, the
517  * initializing std::unique_ptr<Cgu::Thread::Thread> object will be
518  * left unchanged. (It is often not worth checking for this
519  * exception, as it means either memory is exhausted or pthread has
520  * run out of other resources to create new mutexes.)
521  * @note 1. It is not necessary to check that the thread parameter
522  * represents a correctly started thread (that is, that thr.get() does
523  * not return 0) before this constructor is invoked, because that can
524  * be done after construction by calling JoinableHandle::is_managing()
525  * (a JoinableHangle object can safely handle a case where thr.get()
526  * does return 0). This enables a JoinableHandle object to be
527  * directly initialized by this constructor from a call to
528  * Thread::Thread::start().
529  * @note 2. No synchronization is carried out with respect to the
530  * initializing std::unique_ptr object. This is because such an
531  * object is usually passed to this constructor as a temporary, which
532  * is only visible and accessible in the thread carrying out the move
533  * operation, in which case synchronization would represent pointless
534  * overhead. In a case where the user uses std::move to force a move
535  * from a named std::unique_ptr object, and that named object's
536  * lifetime is managed by (or the object is otherwise accessed by) a
537  * different thread than the one making the move, the user must carry
538  * out her own synchronization with respect to that different thread,
539  * as the initializing std::unique_ptr object will be mutated by the
540  * move.
541  * @note 3. If the library is compiled using the --with-auto-ptr
542  * configuration option, then this constructor's signature is
543  * JoinableHandle(std::auto_ptr<Cgu::Thread::Thread> thr, Action act)
544  * in order to retain compatibility with the 1.2 series of the library
545  * @sa JoinableHandle::is_managing().
546  */
547 #ifdef CGU_USE_AUTO_PTR
548  JoinableHandle(std::auto_ptr<Cgu::Thread::Thread> thr, Action act): action(act), detached(false), thread(thr.release()) {}
549 #else
550  JoinableHandle(std::unique_ptr<Cgu::Thread::Thread> thr, Action act): action(act), detached(false), thread(std::move(thr)) {}
551 #endif
552 
553 /**
554  * This constructor initializes a new JoinableHandle object with an
555  * existing JoinableHandle object. This is a move operation which
556  * transfers ownership to the new object.
557  * @param h The initializing JoinableHandle object, which will cease
558  * to hold a valid Thread::Thread object after the initialization has
559  * taken place.
560  * @exception Cgu::Thread::MutexError Throws this exception if
561  * initialization of the internal mutex fails. The constructor is
562  * strongly exception safe: if Cgu::Thread::MutexError is thrown, the
563  * initializing Cgu::Thread::JoinableHandle object will be left
564  * unchanged. (It is often not worth checking for this exception, as
565  * it means either memory is exhausted or pthread has run out of other
566  * resources to create new mutexes.)
567  * @note 1. No synchronization is carried out with respect to the
568  * initializing rvalue. This is because temporaries are only visible
569  * and accessible in the thread carrying out the move operation and
570  * synchronization for them would represent pointless overhead. In a
571  * case where a user uses std::move to force a move from a named
572  * object, and that named object's lifetime is managed by (or the
573  * object is otherwise accessed by) a different thread than the one
574  * making the move, the user must carry out her own synchronization
575  * with respect to that different thread, as the named object will be
576  * mutated by the move.
577  * @note 2. If the library is compiled using the --with-auto-ptr
578  * configuration option, then this constructor's signature is
579  * JoinableHandle(JoinableHandle& h) in order to retain compatibility
580  * with the 1.2 series of the library.
581  */
582 #ifdef CGU_USE_AUTO_PTR
583  JoinableHandle(JoinableHandle& h): action(h.action), detached(h.detached), thread(std::move(h.thread)) {}
584 #else
585  JoinableHandle(JoinableHandle&& h): action(h.action), detached(h.detached), thread(std::move(h.thread)) {}
586 #endif
587 
588 /**
589  * The default constructor. Nothing is managed until the move
590  * assignment operator has been called.
591  * @exception Cgu::Thread::MutexError Throws this exception if
592  * initialization of the internal mutex fails. (It is often not worth
593  * checking for this exception, as it means either memory is exhausted
594  * or pthread has run out of other resources to create new mutexes.)
595  *
596  * Since 2.0.8
597  */
598  JoinableHandle(): action(detach_on_exit), detached(true) {}
599 
600 /**
601  * The destructor will detach a managed thread (if the
602  * Thread::JoinableHandle::detach_on_exit flag is set) or join it (if
603  * the Thread::JoinableHandle::join_on_exit flag is set), unless it
604  * has previously been detached or joined with the detach() or join()
605  * methods. The destructor is thread safe (any thread may destroy the
606  * JoinableHandle object). The destructor will not throw.
607  */
608  ~JoinableHandle();
609 
610 /* Only has effect if --with-glib-memory-slices-compat or
611  * --with-glib-memory-slices-no-compat option picked */
613 };
614 
615 /**
616  * @class CancelBlock thread.h c++-gtk-utils/thread.h
617  * @brief A class enabling the cancellation state of a thread to be
618  * controlled.
619  *
620  * A class enabling the cancellation state of a thread to be
621  * controlled, so as to provide exception safe cancellation state
622  * changes. When the object goes out of scope, cancellation state is
623  * returned to the state it was in prior to its construction.
624  */
625 
626 class CancelBlock {
627  int starting_state;
628 public:
629 /**
630  * This class cannot be copied. The copy constructor is deleted.
631  */
632  CancelBlock(const CancelBlock&) = delete;
633 
634 /**
635  * This class cannot be copied. The assignment operator is deleted.
636  */
637  CancelBlock& operator=(const CancelBlock&) = delete;
638 
639 /**
640  * Makes the thread uncancellable, even if the code passes through a
641  * cancellation point, while the CancelBlock object exists (when the
642  * CancelBlock object ceases to exist, cancellation state is returned
643  * to the state prior to it being constructed). It should only be
644  * called by the thread which created the CancelBlock object. This
645  * method will not throw.
646  * @param old_state Indicates the cancellation state of the calling
647  * thread immediately before this call to block() was made, either
648  * PTHREAD_CANCEL_ENABLE (if the thread was previously cancellable) or
649  * PTHREAD_CANCEL_DISABLE (if this call did nothing because the thread
650  * was already uncancellable).
651  * @return 0 if successful, else a value other than 0.
652  */
653  static int block(int& old_state) {return pthread_setcancelstate(PTHREAD_CANCEL_DISABLE, &old_state);}
654 
655 /**
656  * Makes the thread uncancellable, even if the code passes through a
657  * cancellation point, while the CancelBlock object exists (when the
658  * CancelBlock object ceases to exist, cancellation state is returned
659  * to the state prior to it being constructed). It should only be
660  * called by the thread which created the CancelBlock object. This
661  * method will not throw.
662  * @return 0 if successful, else a value other than 0.
663  */
664  static int block() {int old_state; return block(old_state);}
665 
666 /**
667  * Makes the thread cancellable while the CancelBlock object exists
668  * (when the CancelBlock object ceases to exist, cancellation state is
669  * returned to the state prior to it being constructed). It should
670  * only be called by the thread which created the CancelBlock object.
671  * This method will not throw.
672  * @param old_state Indicates the cancellation state of the calling
673  * thread immediately before this call to unblock() was made, either
674  * PTHREAD_CANCEL_DISABLE (if the thread was previously uncancellable)
675  * or PTHREAD_CANCEL_ENABLE (if this call did nothing because the
676  * thread was already cancellable).
677  * @return 0 if successful, else a value other than 0.
678  */
679  static int unblock(int& old_state) {return pthread_setcancelstate(PTHREAD_CANCEL_ENABLE, &old_state);}
680 
681 /**
682  * Makes the thread cancellable while the CancelBlock object exists
683  * (when the CancelBlock object ceases to exist, cancellation state is
684  * returned to the state prior to it being constructed). It should
685  * only be called by the thread which created the CancelBlock object.
686  * This method will not throw.
687  * @return 0 if successful, else a value other than 0.
688  */
689  static int unblock() {int old_state; return unblock(old_state);}
690 
691 /**
692  * Restores cancellation state to the state it was in immediately
693  * before this CancelBlock object was constructed. It should only be
694  * called by the thread which created the CancelBlock object. This
695  * method will not throw.
696  * @param old_state Indicates the cancellation state of the calling
697  * thread immediately before this call to restore() was made, either
698  * PTHREAD_CANCEL_DISABLE (if the thread was previously uncancellable)
699  * or PTHREAD_CANCEL_ENABLE (if this thread was previously
700  * cancellable).
701  * @return 0 if successful, else a value other than 0.
702  */
703  int restore(int& old_state) {return pthread_setcancelstate(starting_state, &old_state);}
704 
705 /**
706  * Restores cancellation state to the state it was in immediately
707  * before this CancelBlock object was constructed. It should only be
708  * called by the thread which created the CancelBlock object. This
709  * method will not throw.
710  * @return 0 if successful, else a value other than 0.
711  */
712  int restore() {int old_state; return restore(old_state);}
713 
714 /**
715  * The constructor will not throw.
716  * @param blocking Whether the CancelBlock object should start
717  * in blocking mode.
718  */
719  CancelBlock(bool blocking = true);
720 
721 /**
722  * The destructor will put the thread in the cancellation state that
723  * it was in immediately before the CancelBlock object was constructed
724  * (which might be blocking). It will not throw.
725  */
727 
728 /* Only has effect if --with-glib-memory-slices-compat or
729  * --with-glib-memory-slices-no-compat option picked */
731 };
732 
733 /**
734  * @class Exit thread.h c++-gtk-utils/thread.h
735  * @brief A class which can be thrown to terminate the throwing
736  * thread.
737  *
738  * This class can be thrown (instead of calling pthread_exit()) when a
739  * thread wishes to terminate itself and also ensure stack unwinding,
740  * so that destructors of local objects are called. It is caught
741  * automatically by the implementation of Cgu::Thread::Thread::start()
742  * so that it will only terminate the thread throwing it and not the
743  * whole process. See the Cgu::Thread::Thread::cancel() method above,
744  * for use when a thread wishes to terminate another one, and the
745  * caveats on the use of Cgu::Thread::Thread::cancel().
746  *
747  * Do not throw a Cgu::Thread::Exit object in a program with more than
748  * one main loop in order to terminate one of the threads which has
749  * its own main loop. Instead, just cause its main loop to terminate
750  * by, say, calling g_main_loop_quit() on it.
751  */
752 class Exit {};
753 
754 } // namespace Thread
755 
756 } // namespace Cgu
757 
758 #endif