c++-gtk-utils

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

- File List
- File Members

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