c++-gtk-utils
task_manager.h
Go to the documentation of this file.
1 /* Copyright (C) 2012 and 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 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_TASK_MANAGER_H
40 #define CGU_TASK_MANAGER_H
41 
42 #include <deque>
43 #include <utility> // for std::pair, std::move and std::forward
44 #include <exception> // for std::exception
45 #include <memory> // for std::unique_ptr
46 #include <type_traits> // for std::remove_reference and std::remove_const
47 
48 #include <c++-gtk-utils/callback.h>
49 #include <c++-gtk-utils/thread.h>
50 #include <c++-gtk-utils/mutex.h>
54 #include <c++-gtk-utils/emitter.h>
56 
57 namespace Cgu {
58 
59 namespace Thread {
60 
61 struct TaskError: public std::exception {
62  virtual const char* what() const throw() {return "TaskError\n";}
63 };
64 
65 /**
66  * @class Cgu::Thread::TaskManager task_manager.h c++-gtk-utils/task_manager.h
67  * @brief A thread-pool class for managing tasks in multi-threaded programs.
68  * @sa Cgu::Thread::Future Cgu::AsyncResult Cgu::AsyncQueueDispatch Cgu::Callback::post()
69  *
70  * Cgu::Thread::Future operates on the principle of there being one
71  * worker thread per task. In some cases however, it may be better to
72  * have a limited pool of worker threads executing a larger number of
73  * tasks. This class implements this approach via a thread pool.
74  *
75  * One common approach for thread pools of this kind is to set the
76  * maximum number of threads to the number of cores, or some number
77  * less than the number of cores, available on the local machine. How
78  * that can be determined is system specific (on linux it can be
79  * obtained by, for example, inspecting the 'siblings' and 'cpu cores'
80  * fields in /proc/cpuinfo or by using sysconf with the glibc
81  * extension for _SC_NPROCESSORS_ONLN).
82  *
83  * Where the task needs to provide a result, two approaches can be
84  * adopted. First, the task callback can have a Cgu::AsyncResult
85  * object held by Cgu::SharedLockPtr (or by std::shared_ptr having a
86  * thread safe reference count) bound to it. Alternatively, a task
87  * can provide a result asynchronously to a glib main loop by calling
88  * Cgu::Callback::post() when it is ready to do so. From version
89  * 2.0.13, the TaskManager::make_task_result(),
90  * TaskManager::make_task_when(), TaskManager::make_task_when_full()
91  * and TaskManager::make_task_compose() convenience wrapper methods
92  * are provided which will set this up for you (including constructing
93  * appropriate task callbacks) for target functions which return a
94  * value. Tasks can add other tasks, enabling the composition of an
95  * arbitrary number of tasks to obtain a final result.
96  *
97  * TaskManager objects do not provide thread cancellation. Thread
98  * cancellation is incompatible with the task-centred thread pool
99  * model. If task cancellation is wanted, use a Cgu::Thread::Future
100  * (or Cgu::Thread::Thread or Cgu::Thread::JoinableHandle) object
101  * instead, and have a dedicated thread for the cancelable task.
102  *
103  * If glib < 2.32 is installed, g_thread_init() must be called before
104  * any TaskManager objects are constructed, which in turn means that
105  * with glib < 2.32 TaskManager objects may not be constructed as
106  * static objects in global namespace (that is, before g_thread_init()
107  * has been called in the program).
108  *
109  * Any exceptions which propagate from a task will be consumed to
110  * protect the TaskManager object, and to detect whether this has
111  * happened there is a version of the TaskManager::add_task() method
112  * which takes a second argument comprising a 'fail' callback. If an
113  * exception propagates from the 'fail' callback that is also consumed
114  * and a g_critical() message issued.
115  *
116  * Tasks can be aborted by throwing Cgu::Thread::Exit (as well as any
117  * other exception). Where a thread is managed by a TaskManager
118  * object, throwing Cgu::Thread::Exit will only terminate the task and
119  * not the thread on which it is running (and will cause the 'fail'
120  * callback to be executed, if there is one).
121  *
122  * TaskManager objects have no copy constructor or copy assignment
123  * operator, as copying them would have no obvious semantic meaning.
124  * Whilst swapping or moving TaskManager objects would be meaningful,
125  * this is not implemented either because it would require an
126  * additional internal lock to be thread safe, and the circumstances
127  * in which moving or swapping would be useful are limited. Where a
128  * move option is wanted, a TaskManager object can be constructed on
129  * free store and held by std::unique_ptr.
130  *
131  * Here is a compilable example of the calculator class referred to in
132  * the documentation on the AsyncResult but which uses a TaskManager
133  * object so that the calculator class can run more than one thread to
134  * service its calculations:
135  *
136  * @code
137  * #include <vector>
138  * #include <numeric>
139  * #include <ostream>
140  * #include <iostream>
141  *
142  * #include <glib.h>
143  *
144  * #include <c++-gtk-utils/task_manager.h>
145  * #include <c++-gtk-utils/async_result.h>
146  * #include <c++-gtk-utils/shared_ptr.h>
147  * #include <c++-gtk-utils/callback.h>
148  *
149  * using namespace Cgu;
150  *
151  * class Calcs {
152  * Thread::TaskManager tm;
153  * public:
154  * SharedLockPtr<AsyncResult<double>> mean(const std::vector<double>& nums) {
155  * SharedLockPtr<AsyncResult<double>> res(new AsyncResult<double>);
156  * tm.add_task(Callback::lambda<>([=]() {
157  * if (nums.empty()) res->set(0.0);
158  * else res->set(std::accumulate(nums.begin(), nums.end(), 0.0)/nums.size());
159  * }));
160  * return res;
161  * }
162  *
163  * // ... other calculation methods here
164  * };
165  *
166  * int main () {
167  *
168  * g_thread_init(0);
169  * Calcs calcs;
170  * auto res1 = calcs.mean(std::vector<double>({1, 2, 8, 0}));
171  * auto res2 = calcs.mean(std::vector<double>({101, 53.7, 87, 1.2}));
172  *
173  * // ... do something else
174  * std::cout << res1->get() << std::endl;
175  * std::cout << res2->get() << std::endl;
176  *
177  * }
178  * @endcode
179  *
180  * @b The @b TaskManager::make_task_result(), @b TaskManager::make_task_when_full(), @b TaskManager::make_task_when() and @b TaskManager::make_task_compose() @b functions
181  *
182  * From version 2.0.13 the TaskManager::make_task_result(),
183  * TaskManager::make_task_when(), TaskManager::make_task_when_full()
184  * and TaskManager::make_task_compose() convenience wrapper methods
185  * are provided, which construct a task from a target function
186  * returning a value by calling TaskManager::add_task() with an
187  * appropriate callback object. TaskManager::make_task_result()
188  * returns a Cgu::AsyncResult object held by Cgu::SharedLockPtr which
189  * will hold the result provided by the function;
190  * TaskManager::make_task_when(), TaskManager::make_task_when_full()
191  * and TaskManager::make_task_compose() execute a callback in a glib
192  * main loop when the task has completed by passing the callback the
193  * target function's return value. The wrappers therefore provide a
194  * similar interface to the one provided by Cgu::Thread::Future
195  * objects. These wrapper methods can make it easier to compose the
196  * results of a number of different tasks.
197  *
198  * The TaskManager::make_task_result(), TaskManager::make_task_when()
199  * and TaskManager::make_task_when_full() can take a plain function,
200  * static member function or non-static member function as the target
201  * function, and can take up to three arguments in the case of a
202  * non-static member function, and four arguments in the case of any
203  * other function. The arguments can be taken by the function by
204  * value or by reference to const, but not by reference to non-const
205  * (that would not be safe, and a compile error will be generated if
206  * that is attempted). In the case of a non-static member function,
207  * the referenced object whose member function is to be called must
208  * remain in existence until the task concerned has completed.
209  * Alternatively, a callable object such as a std::function object, a
210  * lambda or the return value of std::bind can be passed, which can
211  * have any number of arguments using lambda capture or std::bind (and
212  * which can also bind the referenced object of a non-static member
213  * function by taking a copy of it where that is necessary).
214  * TaskManager::make_task_compose() only takes a callable object for
215  * its task.
216  *
217  * Where a callable object is not passed, internal moving/copying of
218  * arguments for the target function to be represented by the task
219  * takes place (once by invoking the rvalue move constructor or lvalue
220  * copy constructor, as appropriate, when the wrapper methods are
221  * called and, if the argument is not a const reference argument, once
222  * when the task is dispatched by the TaskManager object). Therefore,
223  * if a non-trivial class object is to be received by the target
224  * function as an argument, it is best either (a) if it has a move
225  * constructor, to pass it to the TaskManager::make_task_result(),
226  * TaskManager::make_task_when() or TaskManager::make_task_when_full()
227  * wrapper method as a temporary and have the target function take a
228  * const reference argument, or (b) for it to be constructed on free
229  * store and for the target function to receive it by pointer, by
230  * Cgu::SharedLockPtr, or by a std::shared_ptr implementation which
231  * has a thread-safe reference count. Note also that constructing
232  * callable objects using std::bind will cause copies of arguments to
233  * be made, as will lambda capture, so when not using
234  * TaskManager::make_task_compose() ordinarily it is better to pass a
235  * function pointer with arguments to the wrapper methods rather than
236  * a function object.
237  *
238  * Copying of the return value of the target function represented by
239  * the task may also take place. When a task completes, the return
240  * value will be stored, either in a Cgu::AsyncResult object (if
241  * TaskManager::make_task_result() is called) or for the purposes of
242  * executing the 'when' callback in a glib main loop (if
243  * TaskManager::make_task_when(), TaskManager::make_task_when_full()
244  * or TaskManager::make_task_compose() are called). This storage will
245  * therefore cause the return value type's assignment operator or copy
246  * constructor to be called once unless that type has a move
247  * assignment operator or move constructor, in which case a move
248  * operation will be made. Note that a 'when' callback takes the
249  * stored return value by reference to const and so without any
250  * additional copying upon the 'when' callback being executed in the
251  * main loop.
252  *
253  * With version 2.0.13 of the library, if a callable object which was
254  * not a std::function object (such as a lambda) was passed, the
255  * return value had to be explicitly stated in the call to
256  * make_task_*(). So, if a lambda expression returning an int was to
257  * be executed as a task, TaskManager::make_task_result<int>(),
258  * TaskManager::make_task_when_full<int>(),
259  * TaskManager::make_task_when<int>() or
260  * TaskManager::make_task_compose<int>() had to be called. This is no
261  * longer necessary with version 2.0.14: the return value will be
262  * deduced automatically if it is not stated.
263  *
264  * Here is a compilable example of the calculator class using
265  * TaskManager::make_task_result():
266  * @code
267  * #include <vector>
268  * #include <numeric>
269  * #include <ostream>
270  * #include <iostream>
271  *
272  * #include <glib.h>
273  *
274  * #include <c++-gtk-utils/task_manager.h>
275  * #include <c++-gtk-utils/async_result.h>
276  * #include <c++-gtk-utils/shared_ptr.h>
277  * #include <c++-gtk-utils/callback.h>
278  *
279  * using namespace Cgu;
280  *
281  * class Calcs {
282  * Thread::TaskManager tm;
283  * public:
284  * SharedLockPtr<AsyncResult<double>> mean(const std::vector<double>& nums) {
285  * return tm.make_task_result([=]() {
286  * if (nums.empty()) return 0.0;
287  * return std::accumulate(nums.begin(), nums.end(), 0.0)/nums.size();
288  * });
289  * }
290  *
291  * // ... other calculation methods here
292  * };
293  *
294  * int main () {
295  *
296  * g_thread_init(0);
297  * Calcs calcs;
298  * auto res1 = calcs.mean(std::vector<double>({1, 2, 8, 0}));
299  * auto res2 = calcs.mean(std::vector<double>({101, 53.7, 87, 1.2}));
300  *
301  * // ... do something else
302  * std::cout << res1->get() << std::endl;
303  * std::cout << res2->get() << std::endl;
304  *
305  * }
306  * @endcode
307  *
308  * Here is a reimplementation, using TaskManager::make_task_when(), of
309  * the Number class example with get_primes() method given in the
310  * documentation for Cgu::Thread::Future:
311  * @code
312  * class Numbers {
313  * public:
314  * std::vector<long> get_primes(int n); // calculates the first n primes
315  * // and puts them in a vector
316  * ...
317  * };
318  *
319  * void print_primes(const std::vector<long>& result) {
320  * std::for_each(result.begin(), result.end(), [](long l) {std::cout << l << std::endl;});
321  * }
322  *
323  * Numbers obj;
324  *
325  * // get the first 1,000 primes
326  * using namespace Cgu;
327  * Thread::TaskManager tm;
328  * std::unique_ptr<const Callback::CallbackArg<const std::vector<long>&>> when(
329  * Callback::make(&print_primes)
330  * );
331  * tm.make_task_when(std::move(when),
332  * 0, // default main loop context
333  * obj,
334  * &Numbers::get_primes,
335  * 1000);
336  * @endcode
337  *
338  * Where a member function or ordinary function to be represented by a
339  * task is overloaded, this will cause difficulties in template type
340  * deduction when TaskManager::make_task_result(),
341  * TaskManager::make_task_when() or TaskManager::make_task_when_full()
342  * are called. Explicit disambiguation would be required, for
343  * example:
344  * @code
345  * class Numbers {
346  * public:
347  * int calc(int i);
348  * int calc(double d);
349  * ...
350  * };
351  *
352  * Numbers obj;
353  *
354  * using namespace Cgu;
355  *
356  * Thread::TaskManager tm;
357  *
358  * int i = 1;
359  * double d = 2.0;
360  *
361  * auto res1 =
362  * tm.make_task_result(obj, static_cast<int (Numbers::*)(int)>(&Numbers::calc), i);
363  * auto res2 =
364  * tm.make_task_result(obj, static_cast<int (Numbers::*)(double)>(&Numbers::calc), d);
365  * @endcode
366  */
367 
368 // TODO: this is a work-around for gcc < 4.7, which has a bug which
369 // requires a function whose return value is determined by decltype,
370 // such as make_task_result(Func&&), to be inline. At a suitable
371 // API/ABI break when gcc requirements are updated, this should be
372 // moved to task_manager.tpp.
373 namespace TaskManagerHelper {
374 
375 template <class Ret, class FType>
377  static void exec(FType& f,
378  const SharedLockPtr<AsyncResult<Ret>>& ret) {
379  ret->set(f());
380  }
381  static void do_fail(const SharedLockPtr<AsyncResult<Ret>>& ret) {
382  ret->set_error(); // won't throw
383  }
384 };
385 
386 /*
387  * The FunctorResultExec class is a specialised class which is
388  * necessary because the 'functor member needs to be declared mutable
389  * so that it can bind to the reference to non-const argument of
390  * FunctorResultWrapper::exec(), and thus so that a mutable lambda can
391  * be executed by that function. Because it is so specialised, it is
392  * not suitable for inclusion in the generic interfaces provided in
393  * callback.h. (Except in this specialised usage, it can also be
394  * dangerous, as it allows a member of the callback object to be
395  * mutated: normally this would be undesirable.) An alternative would
396  * have been to put the 'functor' member in a wrapper struct like
397  * MemfunWhenWrapperArgs or FunWhenWrapperArgs, but if 'functor' were
398  * an lvalue that would mean it being copied twice. This is the most
399  * efficient implementation.
400  */
401 template <class Ret, class FType>
403  mutable FType functor;
405 public:
406  void dispatch() const {FunctorResultWrapper<Ret, FType>::exec(functor, ret);}
407  // we don't need to templatize 'ret_' for perfect forwarding - it is
408  // always passed as a lvalue
409  template <class FunctorArg>
410  FunctorResultExec(FunctorArg&& functor_,
411  const SharedLockPtr<AsyncResult<Ret>>& ret_): functor(std::forward<FunctorArg>(functor_)),
412  ret(ret_) {}
413 };
414 
415 } // namespace TaskManagerHelper
416 
417 
418 class TaskManager {
419  public:
421  private:
422  typedef std::pair<std::unique_ptr<const Callback::Callback>,
423  std::unique_ptr<const Callback::Callback>> QueueItemType;
424 
425  struct RefImpl; // reference counted implementation class
426  // it is fine holding RefImpl by plain pointer and not by
427  // IntrusivePtr: it is the only data member this class has, so it
428  // can safely manage that member in its own destructor and other
429  // methods
430  RefImpl* ref_impl;
431 
432  void set_max_threads_impl(unsigned int max);
433  public:
434 /**
435  * This class cannot be copied. The copy constructor is deleted.
436  */
437  TaskManager(const TaskManager&) = delete;
438 
439 /**
440  * This class cannot be copied. The assignment operator is deleted.
441  */
442  TaskManager& operator=(const TaskManager&) = delete;
443 
444  /**
445  * Gets the maximum number of threads which the TaskManager object is
446  * currently set to run in the thread pool. This value is established
447  * initially by the 'max' argument passed to the TaskManager
448  * constructor and can subequently be changed by calling
449  * set_max_threads() or change_max_threads(). The default value is 8.
450  * This method will not throw and is thread safe.
451  * @return The maximum number of threads.
452  *
453  * Since 2.0.12
454  */
455  unsigned int get_max_threads() const;
456 
457  /**
458  * Gets the minimum number of threads which the TaskManager object
459  * will run in the thread pool (these threads will last until
460  * stop_all() is called or the TaskManager object is destroyed).
461  * This value is established by the 'min' argument passed to the
462  * TaskManager constructor and cannot subequently be changed. The
463  * default is 0. This method will not throw and is thread safe.
464  * @return The minimum number of threads.
465  *
466  * Since 2.0.12
467  */
468  unsigned int get_min_threads() const;
469 
470  /**
471  * Gets the number of threads which the TaskManager object is
472  * currently running in the thread pool, including those blocking
473  * waiting for a task. This value could be greater than the number
474  * returned by get_max_threads() if set_max_threads() has recently
475  * been called with a value which is less than that number but not
476  * enough tasks have since completed to reduce the number of running
477  * threads to the new value set. This method will not throw and is
478  * thread safe.
479  * @return The number of threads running in the thread pool,
480  * including those blocking waiting for a task.
481  *
482  * Since 2.0.12
483  */
484  unsigned int get_used_threads() const;
485 
486  /**
487  * Gets the number of tasks which the TaskManager object is at
488  * present either running in the thread pool or has queued for
489  * execution. This value will be less than the number returned by
490  * get_used_threads() if threads in the thread pool are currently
491  * waiting to receive tasks for execution. This method will not
492  * throw and is thread safe.
493  * @return The number of tasks either running or queued for
494  * execution.
495  *
496  * Since 2.0.12
497  */
498  unsigned int get_tasks() const;
499 
500  /**
501  * Sets the maximum number of threads which the TaskManager object
502  * will currently run in the thread pool. If this is less than the
503  * current number of running threads, the number of threads actually
504  * running will only be reduced as tasks complete, or as idle
505  * timeouts expire. This method does nothing if stop_all() has
506  * previously been called. This method is thread safe.
507  * @param max The maximum number of threads which the TaskManager
508  * object will currently run in the thread pool. This method will
509  * not set the maximum value of threads to a value less than that
510  * returned by get_min_threads(), nor to a value less than 1.
511  * @exception std::bad_alloc If this call is passed a value for 'max'
512  * which increases the maximum number of threads from its previous
513  * setting and tasks are currently queued for execution, new threads
514  * will be started for the queued tasks, so this exception may be
515  * thrown on starting the new threads if memory is exhausted and the
516  * system throws in that case. (On systems with
517  * over-commit/lazy-commit combined with virtual memory (swap), it is
518  * rarely useful to check for memory exhaustion).
519  * @exception Cgu::Thread::TaskError If this call is passed a value
520  * for 'max' which increases the maximum number of threads from its
521  * previous setting and tasks are currently queued for execution, new
522  * threads will be started for the queued tasks, so this exception
523  * may be thrown on starting the new threads if a thread fails to
524  * start correctly (this would mean that memory is exhausted, the
525  * pthread thread limit has been reached or pthread has run out of
526  * other resources to start new threads).
527  *
528  * Since 2.0.12
529  */
530  void set_max_threads(unsigned int max);
531 
532  /**
533  * This will increase, or if 'delta' is negative reduce, the maximum
534  * number of threads which the TaskManager object will currently run
535  * in the thread pool by the value of 'delta'. The purpose of this
536  * is to enable a task to increment the maximum thread number where
537  * it is about to enter a call which may block for some time, with a
538  * view to decrementing it later when it has finished making blocking
539  * calls, so as to enable another thread to keep a core active. If
540  * 'delta' is negative and results in a max_threads value of less
541  * than the current number of running threads, the number of threads
542  * actually running will only be reduced as tasks complete, or as
543  * idle timeouts expire. This method does nothing if stop_all() has
544  * previously been called. This method is thread safe.
545  * @param delta The change (positive or negative) to the maximum
546  * number of threads which the TaskManager object will currently run
547  * in the thread pool. This method will not set the maximum value of
548  * threads to a value less than that returned by get_min_threads(),
549  * nor to a value less than 1.
550  * @exception std::bad_alloc If this call is passed a positive value
551  * and tasks are currently queued for execution, a new thread or
552  * threads will be started for the queued tasks, so this exception
553  * may be thrown on starting a new thread if memory is exhausted and
554  * the system throws in that case. (On systems with
555  * over-commit/lazy-commit combined with virtual memory (swap), it is
556  * rarely useful to check for memory exhaustion).
557  * @exception Cgu::Thread::TaskError If this call is passed a
558  * positive value and tasks are currently queued for execution, a new
559  * thread or threads will be started for the queued tasks, so this
560  * exception may be thrown on starting a new thread if it fails to
561  * start correctly (this would mean that memory is exhausted, the
562  * pthread thread limit has been reached or pthread has run out of
563  * other resources to start new threads).
564  *
565  * Since 2.0.14
566  */
567  void change_max_threads(int delta);
568 
569  /**
570  * Gets the length of time in milliseconds that threads greater in
571  * number than the minimum and not executing any tasks will remain in
572  * existence waiting for new tasks. This value is established
573  * initially by the 'idle' argument passed to the TaskManager
574  * constructor and can subequently be changed by calling
575  * set_idle_time(). The default value is 10000 (10 seconds). This
576  * method will not throw and is thread safe.
577  * @return The idle time in milliseconds.
578  *
579  * Since 2.0.12
580  */
581  unsigned int get_idle_time() const;
582 
583  /**
584  * Sets the length of time in milliseconds that threads greater in
585  * number than the minimum and not executing any tasks will remain in
586  * existence waiting for new tasks. This will only have effect for
587  * threads in the pool which begin waiting for new tasks after this
588  * method is called. This method will not throw and is thread safe.
589  * @param idle The length of the idle time in milliseconds during
590  * which threads will remain waiting for new tasks.
591  *
592  * Since 2.0.12
593  */
594  void set_idle_time(unsigned int idle);
595 
596  /**
597  * Gets the current blocking setting, which determines whether calls
598  * to stop_all() and the destructor will block waiting for all
599  * remaining tasks to complete. This value is established initially
600  * by the 'blocking' argument passed to the TaskManager constructor
601  * and can subequently be changed by calling set_blocking(). This
602  * method will not throw and is thread safe.
603  * @return The current blocking setting.
604  *
605  * Since 2.0.12
606  */
607  bool get_blocking() const;
608 
609  /**
610  * Sets the current blocking setting, which determines whether calls
611  * to stop_all() and the destructor will block waiting for all
612  * remaining tasks to complete. This method cannot be called after
613  * stop_all() has been called (if that is attempted,
614  * Cgu::Thread::TaskError will be thrown). It is thread safe.
615  * @param blocking The new blocking setting.
616  * @exception Cgu::Thread::TaskError This exception will be thrown if
617  * stop_all() has previously been called.
618  *
619  * Since 2.0.12
620  */
621  void set_blocking(bool blocking);
622 
623  /**
624  * Gets the current StopMode setting (either
625  * Cgu::Thread::TaskManager::wait_for_running or
626  * Cgu::Thread::TaskManager::wait_for_all) executed when running
627  * stop_all() or when the destructor is called. See the
628  * documentation on stop_all() for an explanation of the setting.
629  * This value is established initially by the 'mode' argument passed
630  * to the TaskManager constructor and can subequently be changed by
631  * calling set_stop_mode(). This method will not throw and is thread
632  * safe.
633  * @return The current StopMode setting.
634  *
635  * Since 2.0.12
636  */
637  StopMode get_stop_mode() const;
638 
639  /**
640  * Sets the current StopMode setting (either
641  * Cgu::Thread::TaskManager::wait_for_running or
642  * Cgu::Thread::TaskManager::wait_for_all) executed when running
643  * stop_all() or when the destructor is called. See the
644  * documentation on stop_all() for an explanation of the setting.
645  * This method will not throw and is thread safe.
646  * @param mode The new StopMode setting.
647  *
648  * Since 2.0.12
649  */
650  void set_stop_mode(StopMode mode);
651 
652  /**
653  * This will cause the TaskManager object to stop running tasks. The
654  * precise effect depends on the current StopMode and blocking
655  * settings. If StopMode is set to
656  * Cgu::Thread::TaskManager::wait_for_running, all queued tasks which
657  * are not yet running on a thread will be dispensed with, but any
658  * already running will be left to complete normally. If StopMode is
659  * set to Cgu::Thread::TaskManager::wait_for_all, both already
660  * running tasks and all tasks already queued will be permitted to
661  * execute and complete normally. If the blocking setting is set to
662  * true, this method will wait until all the tasks still to execute
663  * have finished before returning, and if false it will return
664  * straight away.
665  *
666  * After this method has been called, any attempt to add further
667  * tasks with the add_task() method will fail, and add_task() will
668  * throw Cgu::Thread::TaskError.
669  *
670  * This method is thread safe (any thread may call it) unless the
671  * blocking setting is true, in which case no task running on the
672  * TaskManager object may call this method.
673  * @exception std::bad_alloc This exception will be thrown if memory
674  * is exhausted and the system throws in that case. (On systems with
675  * over-commit/lazy-commit combined with virtual memory (swap), it is
676  * rarely useful to check for memory exhaustion).
677  * @exception Cgu::Thread::TaskError This exception will be thrown if
678  * stop_all() has previously been called, unless that previous call
679  * threw std::bad_alloc: if std::bad_alloc is thrown, this method may
680  * be called again to stop all threads, once the memory deficiency is
681  * dealt with, but no other methods of the TaskManager object should
682  * be called.
683  *
684  * Since 2.0.12
685  */
686  void stop_all();
687 
688  /**
689  * This method adds a new task. If one or more threads in the pool
690  * are currently blocking and waiting for a task, then the task will
691  * begin executing immediately in one of the threads. If not, and
692  * the value returned by get_used_threads() is less than the value
693  * returned by get_max_threads(), a new thread will start and the
694  * task will execute immediately in the new thread. Otherwise, the
695  * task will be queued for execution as soon as a thread becomes
696  * available. Tasks will be executed in the order in which they are
697  * added to the ThreadManager object. This method is thread safe
698  * (any thread may call it, including any task running on the
699  * TaskManager object).
700  *
701  * A task may terminate itself prematurely by throwing
702  * Cgu::Thread::Exit. In addition, the implementation of TaskManager
703  * will consume any other exception escaping from the task callback
704  * and safely terminate the task concerned in order to protect the
705  * integrity of the TaskManager object. Where detecting any of these
706  * outcomes is important (usually it won't be), the two argument
707  * version of this method is available so that a 'fail' callback can
708  * be executed in these circumstances.
709  *
710  * @param task A callback representing the new task, as constructed
711  * by the Callback::make(), Callback::make_ref() or
712  * Callback::lambda() factory functions. Ownership is taken of this
713  * callback, and it will be disposed of when it has been finished
714  * with. The destructors of any bound arguments in the callback must
715  * not throw.
716  * @exception std::bad_alloc This exception will be thrown if memory
717  * is exhausted and the sytem throws in that case. (On systems with
718  * over-commit/lazy-commit combined with virtual memory (swap), it is
719  * rarely useful to check for memory exhaustion). If this exception
720  * is thrown, the 'task' callback will be disposed of.
721  * @exception Cgu::Thread::TaskError This exception will be thrown if
722  * stop_all() has previously been called. It will also be thrown if
723  * is_error() would return true because this class's internal thread
724  * pool loop implementation has thrown std::bad_alloc, or a thread
725  * has failed to start correctly. (On systems with
726  * over-commit/lazy-commit combined with virtual memory (swap), it is
727  * rarely useful to check for memory exhaustion, but there may be
728  * some specialized cases where the return value of is_error() is
729  * useful.) If this exception is thrown, the 'task' callback will be
730  * disposed of.
731  *
732  * Since 2.0.12
733  */
734  void add_task(const Callback::Callback* task) {
735 #ifdef CGU_USE_AUTO_PTR
736  add_task(std::auto_ptr<const Callback::Callback>(task),
737  std::auto_ptr<const Callback::Callback>());
738 #else
739  add_task(std::unique_ptr<const Callback::Callback>(task),
740  std::unique_ptr<const Callback::Callback>());
741 #endif
742  }
743 
744  /**
745  * This method adds a new task. If one or more threads in the pool
746  * are currently blocking and waiting for a task, then the task will
747  * begin executing immediately in one of the threads. If not, and
748  * the value returned by get_used_threads() is less than the value
749  * returned by get_max_threads(), a new thread will start and the
750  * task will execute immediately in the new thread. Otherwise, the
751  * task will be queued for execution as soon as a thread becomes
752  * available. Tasks will be executed in the order in which they are
753  * added to the ThreadManager object. This method is thread safe
754  * (any thread may call it, including any task running on the
755  * TaskManager object).
756  *
757  * A task may terminate itself prematurely by throwing
758  * Cgu::Thread::Exit. In addition, the implementation of TaskManager
759  * will consume any other exception escaping from the task callback
760  * and safely terminate the task concerned in order to protect the
761  * integrity of the TaskManager object. Where detecting any of these
762  * outcomes is important (usually it won't be), a callback can be
763  * passed to the 'fail' argument which will execute if, and only if,
764  * either Cgu::Thread::Exit is thrown or some other exception has
765  * propagated from the task. This 'fail' callback is different from
766  * the 'fail' callback of Cgu::Thread::Future objects (programming
767  * for many tasks to a lesser number of threads requires different
768  * approaches from programming for one thread per task), and it
769  * executes in the task thread rather than executing in a glib main
770  * loop (however, the 'fail' callback can of course call
771  * Cgu::Callback::post() to execute another callback in a main loop,
772  * if that is what is wanted).
773  *
774  * @param task A callback representing the new task, as constructed
775  * by the Callback::make(), Callback::make_ref() or
776  * Callback::lambda() factory functions.
777  * @param fail A callback which will be executed if the function
778  * executed by the 'task' callback exits by throwing Thread::Exit or
779  * some other exception. If an exception propagates from the
780  * function represented by the 'fail' callback, this will be consumed
781  * to protect the TaskManager object, and a g_critical() warning will
782  * be issued.
783  * @exception std::bad_alloc This exception will be thrown if memory
784  * is exhausted and the sytem throws in that case. (On systems with
785  * over-commit/lazy-commit combined with virtual memory (swap), it is
786  * rarely useful to check for memory exhaustion).
787  * @exception Cgu::Thread::TaskError This exception will be thrown if
788  * stop_all() has previously been called. It will also be thrown if
789  * is_error() would return true because this class's internal thread
790  * pool loop implementation has thrown std::bad_alloc, or a thread
791  * has failed to start correctly. (On systems with
792  * over-commit/lazy-commit combined with virtual memory (swap), it is
793  * rarely useful to check for memory exhaustion, but there may be
794  * some specialized cases where the return value of is_error() is
795  * useful.)
796  * @note 1. Question: why does the single argument version of
797  * add_task() take a pointer, and this version take the callbacks by
798  * std::unique_ptr? Answer: The two argument version of add_task()
799  * takes its arguments by std::unique_ptr in order to be exception
800  * safe if the first callback to be constructed is constructed
801  * correctly but construction of the second callback object throws.
802  * @note 2. If the library is compiled using the --with-auto-ptr
803  * configuration option, then this method's signature is
804  * add_task(std::auto_ptr<const Callback::Callback>,
805  * std::auto_ptr<const Callback::Callback>) in order to retain
806  * compatibility with the 1.2 series of the library.
807  *
808  * Since 2.0.12
809  */
810 #ifdef CGU_USE_AUTO_PTR
811  void add_task(std::auto_ptr<const Callback::Callback> task,
812  std::auto_ptr<const Callback::Callback> fail);
813 #else
814  void add_task(std::unique_ptr<const Callback::Callback> task,
815  std::unique_ptr<const Callback::Callback> fail);
816 #endif
817 
818  /**
819  * This will return true if a thread required by the thread pool has
820  * failed to start correctly because of memory exhaustion or because
821  * pthread has run out of other resources to start new threads, or
822  * because an internal operation has thrown std::bad_alloc. (On
823  * systems with over-commit/lazy-commit combined with virtual memory
824  * (swap), it is rarely useful to check for memory exhaustion, and
825  * even more so where glib is used, as that terminates a program if
826  * memory cannot be obtained from the operating system, but there may
827  * be some specialized cases where the return value of this method is
828  * useful - this class does not use any glib functions which might
829  * cause such termination.) This method will not throw and is thread
830  * safe.
831  *
832  * Since 2.0.12
833  */
834  bool is_error() const;
835 
836  /**
837  * This is a wrapper which will take a member function pointer to a
838  * member function which returns a value, together with arguments,
839  * and constructs a TaskManager task which will execute that function
840  * by calling add_task() with an appropriate callback object, and
841  * returns a Cgu::AsyncResult object (held by Cgu::SharedLockPtr)
842  * which will provide the value that the function returns. It is
843  * thread safe (any thread may call this method, including another
844  * task running on the TaskManager object). Apart from the absence
845  * of a 'one thread per task' model, this method therefore provides a
846  * similar interface to the one provided by Cgu::Thread::Future. See
847  * the documentation on add_task() for further information about how
848  * task execution works.
849  *
850  * This method can take up to three bound arguments for the target
851  * member function.
852  *
853  * If the function passed to this method exits by throwing
854  * Thread::Exit or some other exception, then the returned
855  * Cgu::AsyncResult object's get() method will unblock and its
856  * get_error() method will return -1.
857  *
858  * @param t The object whose member function passed to this method is
859  * to execute as a task.
860  * @param func The member function to be executed as a task.
861  * @param args The arguments to be passed to that member function.
862  * @exception std::bad_alloc This exception will be thrown if memory
863  * is exhausted and the sytem throws in that case. (On systems with
864  * over-commit/lazy-commit combined with virtual memory (swap), it is
865  * rarely useful to check for memory exhaustion).
866  * @exception Cgu::Thread::TaskError This exception will be thrown if
867  * stop_all() has previously been called. It will also be thrown if
868  * is_error() would return true because this class's internal thread
869  * pool loop implementation has thrown std::bad_alloc, or a thread
870  * has failed to start correctly. (On systems with
871  * over-commit/lazy-commit combined with virtual memory (swap), it is
872  * rarely useful to check for memory exhaustion, but there may be
873  * some specialized cases where the return value of is_error() is
874  * useful.)
875  * @note This method will also throw if the copy or move constructor
876  * of a bound argument throws.
877  *
878  * Since 2.0.13
879  */
880 
881  template <class Ret, class... Params, class... Args, class T>
883  Ret (T::*func)(Params...),
884  Args&&... args);
885 
886  /**
887  * This is a wrapper which will take a member function pointer to a
888  * member function which returns a value, together with arguments,
889  * and constructs a TaskManager task which will execute that function
890  * by calling add_task() with an appropriate callback object, and
891  * causes the 'when' callback passed as an argument to this method to
892  * be executed by a glib main loop if and when the task finishes
893  * correctly - the 'when' callback is passed the member function's
894  * return value when it is invoked. It is thread safe (any thread
895  * may call this method, including another task running on the
896  * TaskManager object). Apart from the absence of a 'one thread per
897  * task' model, this method therefore provides a similar interface to
898  * the one provided by Cgu::Thread::Future. See the documentation on
899  * add_task() for further information about how task execution works.
900  *
901  * This method can take up to three bound arguments for the target
902  * member function.
903  *
904  * Note that unlike add_task(), but like the 'fail' callback of
905  * Cgu::Thread::Future objects, if a fail callback is provided to
906  * this method and it executes, it will execute in the glib main loop
907  * whose GMainContext object is passed to the 'context' argument of
908  * this method.
909  *
910  * Note also that if releasers are provided for the 'when' or 'fail'
911  * callbacks, these are passed by pointer and not by reference (this
912  * is so that a NULL pointer can indicate that no releaser is to be
913  * provided). If provided, a releaser will enable automatic
914  * disconnection of the 'when' or 'fail' callback, if the object
915  * having the callback function as a member is destroyed. For this to
916  * be race free, the lifetime of that object must be controlled by
917  * the thread in whose main loop the 'when' or 'fail' callback will
918  * execute.
919  *
920  * The make_task_when() method is similar to this method but provides
921  * an abbreviated set of paramaters suitable for most cases. This
922  * method is for use where releasers or a 'fail' callback are
923  * required.
924  *
925  * @param when A callback which will be executed if and when the
926  * function passed to this method finishes correctly. The callback is
927  * passed that function's return value when it is invoked. It will
928  * execute in the glib main loop whose GMainContext object is passed
929  * to the 'context' argument of this method.
930  * @param when_releaser A pointer to a releaser object for automatic
931  * disconnection of the 'when' callback if the object of which the
932  * callback function is a member is destroyed. A value of
933  * 0/NULL/nullptr indicates no releaser.
934  * @param fail A callback which will be executed if the 'when'
935  * callback does not execute. This would happen if the function
936  * passed to this method exits by throwing Thread::Exit or some other
937  * exception or the copy constructor of a non-reference argument of
938  * that function throws, or if the 'when' callback does not execute
939  * because the internal implementation of this wrapper throws
940  * std::bad_alloc (which will not happen if the library has been
941  * installed using the –with-glib-memory-slices-no-compat
942  * configuration option: instead glib will terminate the program if
943  * it is unable to obtain memory from the operating system). If an
944  * exception propagates from the function represented by the 'fail'
945  * callback, this will be consumed to protect the TaskManager object,
946  * and a g_critical() warning will be issued. The callback will
947  * execute in the glib main loop whose GMainContext object is passed
948  * to the 'context' argument of this method. An empty
949  * std::unique_ptr object indicates no 'fail' callback.
950  * @param fail_releaser A pointer to a releaser object for automatic
951  * disconnection of the 'fail' callback if the object of which the
952  * callback function is a member is destroyed. A value of
953  * 0/NULL/nullptr indicates no releaser.
954  * @param priority The priority to be given in the main loop to the
955  * 'when' callback or any 'fail' callback. In ascending order of
956  * priorities, priorities are G_PRIORITY_LOW,
957  * G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT
958  * and G_PRIORITY_HIGH. This determines the order in which the
959  * callback will appear in the event list in the main loop, not the
960  * priority which the OS will adopt.
961  * @param context The glib main context of the main loop in which the
962  * 'when' callback or any 'fail' callback is to be executed. A value
963  * 0/NULL/nullptr will cause the callback to be executed in the main
964  * program loop.
965  * @param t The object whose member function passed to this method is
966  * to execute as a task.
967  * @param func The member function to be executed as a task.
968  * @param args The arguments to be passed to that member function.
969  * @exception std::bad_alloc This exception will be thrown if memory
970  * is exhausted and the sytem throws in that case. (On systems with
971  * over-commit/lazy-commit combined with virtual memory (swap), it is
972  * rarely useful to check for memory exhaustion).
973  * @exception Cgu::Thread::TaskError This exception will be thrown if
974  * stop_all() has previously been called. It will also be thrown if
975  * is_error() would return true because this class's internal thread
976  * pool loop implementation has thrown std::bad_alloc, or a thread
977  * has failed to start correctly. (On systems with
978  * over-commit/lazy-commit combined with virtual memory (swap), it is
979  * rarely useful to check for memory exhaustion, but there may be
980  * some specialized cases where the return value of is_error() is
981  * useful.)
982  * @note 1. This method will also throw if the copy or move
983  * constructor of a bound argument throws.
984  * @note 2. If a 'when_releaser' or a 'fail_releaser' argument is
985  * provided, it is in theory possible (if memory is exhausted and the
986  * system throws in that case) that an internal SafeEmitterArg object
987  * will throw std::bad_alloc when emitting/executing the 'when' or
988  * 'fail' callback in the glib main loop, with the result that the
989  * relevant callback will not execute (instead the exception will be
990  * consumed and a g_critical() warning will be issued). This is
991  * rarely of any relevance because glib will abort the program if it
992  * is itself unable to obtain memory from the operating system.
993  * However, where it is relevant, design the program so that it is
994  * not necessary to provide a releaser object.
995  * @note 3. If the library is compiled using the --with-auto-ptr
996  * configuration option, then this method uses std::auto_ptr in place
997  * of std::unique_ptr in its signature in order to retain
998  * compatibility with the 1.2 series of the library.
999  *
1000  * Since 2.0.13
1001  */
1002  template <class Ret, class... Params, class... Args, class T>
1003 #ifdef CGU_USE_AUTO_PTR
1004  void make_task_when_full(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1005  Cgu::Releaser* when_releaser,
1006  std::auto_ptr<const Cgu::Callback::Callback> fail,
1007  Cgu::Releaser* fail_releaser,
1008  gint priority,
1009  GMainContext* context,
1010  T& t,
1011  Ret (T::*func)(Params...),
1012  Args&&... args);
1013 #else
1014  void make_task_when_full(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1015  Cgu::Releaser* when_releaser,
1016  std::unique_ptr<const Cgu::Callback::Callback> fail,
1017  Cgu::Releaser* fail_releaser,
1018  gint priority,
1019  GMainContext* context,
1020  T& t,
1021  Ret (T::*func)(Params...),
1022  Args&&... args);
1023 #endif
1024 
1025  /**
1026  * This is an abbreviated version of make_task_when_full(), which is
1027  * for use when it is known that the member function passed to this
1028  * method, and the copy constructors of any non-reference bound
1029  * arguments passed to it, do not throw, and the user is not
1030  * interested in std::bad_alloc and does not need a Cgu::Releaser
1031  * object for the 'when' callback (which is likely to cover the
1032  * majority of uses, particularly when composing tasks using glib
1033  * because glib terminates the program if it is unable to obtain
1034  * memory).
1035  *
1036  * This method can take up to three bound arguments for the target
1037  * member function.
1038  *
1039  * Like make_task_when_full(), this method is a wrapper which will
1040  * take a member function pointer to a member function which returns
1041  * a value, together with arguments, and constructs a TaskManager
1042  * task which will execute that function by calling add_task() with
1043  * an appropriate callback object, and causes the 'when' callback
1044  * passed as an argument to this method to be executed by a glib main
1045  * loop if and when the task finishes correctly - the 'when' callback
1046  * is passed the member function's return value when it is invoked.
1047  * It is thread safe (any thread may call this method, including
1048  * another task running on the TaskManager object). Apart from the
1049  * absence of a 'one thread per task' model, this method therefore
1050  * provides a similar interface to the one provided by
1051  * Cgu::Thread::Future. See the documentation on add_task() for
1052  * further information about how task execution works.
1053  *
1054  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
1055  * in the main loop.
1056  *
1057  * @param when A callback which will be executed if and when the
1058  * function passed to this method finishes correctly. The callback is
1059  * passed that function's return value when it is invoked. It will
1060  * execute in the glib main loop whose GMainContext object is passed
1061  * to the 'context' argument of this method.
1062  * @param context The glib main context of the main loop in which the
1063  * 'when' callback is to be executed. A value 0/NULL/nullptr will
1064  * cause the callback to be executed in the main program loop.
1065  * @param t The object whose member function passed to this method is
1066  * to execute as a task.
1067  * @param func The member function to be executed as a task.
1068  * @param args The arguments to be passed to that member function.
1069  * @exception std::bad_alloc This exception will be thrown if memory
1070  * is exhausted and the sytem throws in that case. (On systems with
1071  * over-commit/lazy-commit combined with virtual memory (swap), it is
1072  * rarely useful to check for memory exhaustion).
1073  * @exception Cgu::Thread::TaskError This exception will be thrown if
1074  * stop_all() has previously been called. It will also be thrown if
1075  * is_error() would return true because this class's internal thread
1076  * pool loop implementation has thrown std::bad_alloc, or a thread
1077  * has failed to start correctly. (On systems with
1078  * over-commit/lazy-commit combined with virtual memory (swap), it is
1079  * rarely useful to check for memory exhaustion, but there may be
1080  * some specialized cases where the return value of is_error() is
1081  * useful.)
1082  * @note 1. This method will also throw if the copy or move
1083  * constructor of a bound argument throws.
1084  * @note 2. If the library is compiled using the --with-auto-ptr
1085  * configuration option, then this method uses std::auto_ptr in place
1086  * of std::unique_ptr in its signature in order to retain
1087  * compatibility with the 1.2 series of the library.
1088  *
1089  * Since 2.0.13
1090  */
1091  template <class Ret, class... Params, class... Args, class T>
1092 #ifdef CGU_USE_AUTO_PTR
1093  void make_task_when(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1094  GMainContext* context,
1095  T& t,
1096  Ret (T::*func)(Params...),
1097  Args&&... args) {
1098  static_assert(sizeof...(Args) < 4,
1099  "No greater than three bound arguments can be passed to "
1100  "TaskManager::make_task_when() taking a member function.");
1101 
1102  make_task_when_full(when,
1103  0,
1104  std::auto_ptr<const Cgu::Callback::Callback>(),
1105  0,
1106  G_PRIORITY_DEFAULT,
1107  context,
1108  t,
1109  func,
1110  std::forward<Args>(args)...);
1111  }
1112 #else
1113  void make_task_when(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1114  GMainContext* context,
1115  T& t,
1116  Ret (T::*func)(Params...),
1117  Args&&... args) {
1118  static_assert(sizeof...(Args) < 4,
1119  "No greater than three bound arguments can be passed to "
1120  "TaskManager::make_task_when() taking a member function.");
1121 
1122  make_task_when_full(std::move(when),
1123  0,
1124  std::unique_ptr<const Cgu::Callback::Callback>(),
1125  0,
1126  G_PRIORITY_DEFAULT,
1127  context,
1128  t,
1129  func,
1130  std::forward<Args>(args)...);
1131  }
1132 #endif
1133 
1134  /**
1135  * This is a wrapper which will take a member function pointer to a
1136  * member function which returns a value, together with arguments,
1137  * and constructs a TaskManager task which will execute that function
1138  * by calling add_task() with an appropriate callback object, and
1139  * returns a Cgu::AsyncResult object (held by Cgu::SharedLockPtr)
1140  * which will provide the value that the function returns. It is
1141  * thread safe (any thread may call this method, including another
1142  * task running on the TaskManager object). Apart from the absence
1143  * of a 'one thread per task' model, this method therefore provides a
1144  * similar interface to the one provided by Cgu::Thread::Future. See
1145  * the documentation on add_task() for further information about how
1146  * task execution works.
1147  *
1148  * This method can take up to three bound arguments for the target
1149  * member function.
1150  *
1151  * If the function passed to this method exits by throwing
1152  * Thread::Exit or some other exception, then the returned
1153  * Cgu::AsyncResult object's get() method will unblock and its
1154  * get_error() method will return -1.
1155  *
1156  * @param t The object whose member function passed to this method is
1157  * to execute as a task.
1158  * @param func The member function to be executed as a task.
1159  * @param args The arguments to be passed to that member function.
1160  * @exception std::bad_alloc This exception will be thrown if memory
1161  * is exhausted and the sytem throws in that case. (On systems with
1162  * over-commit/lazy-commit combined with virtual memory (swap), it is
1163  * rarely useful to check for memory exhaustion).
1164  * @exception Cgu::Thread::TaskError This exception will be thrown if
1165  * stop_all() has previously been called. It will also be thrown if
1166  * is_error() would return true because this class's internal thread
1167  * pool loop implementation has thrown std::bad_alloc, or a thread
1168  * has failed to start correctly. (On systems with
1169  * over-commit/lazy-commit combined with virtual memory (swap), it is
1170  * rarely useful to check for memory exhaustion, but there may be
1171  * some specialized cases where the return value of is_error() is
1172  * useful.)
1173  * @note This method will also throw if the copy or move constructor
1174  * of a bound argument throws.
1175  *
1176  * Since 2.0.13
1177  */
1178 
1179  template <class Ret, class... Params, class... Args, class T>
1181  Ret (T::*func)(Params...) const,
1182  Args&&... args);
1183 
1184  /**
1185  * This is a wrapper which will take a member function pointer to a
1186  * member function which returns a value, together with arguments,
1187  * and constructs a TaskManager task which will execute that function
1188  * by calling add_task() with an appropriate callback object, and
1189  * causes the 'when' callback passed as an argument to this method to
1190  * be executed by a glib main loop if and when the task finishes
1191  * correctly - the 'when' callback is passed the member function's
1192  * return value when it is invoked. It is thread safe (any thread
1193  * may call this method, including another task running on the
1194  * TaskManager object). Apart from the absence of a 'one thread per
1195  * task' model, this method therefore provides a similar interface to
1196  * the one provided by Cgu::Thread::Future. See the documentation on
1197  * add_task() for further information about how task execution works.
1198  *
1199  * This method can take up to three bound arguments for the target
1200  * member function.
1201  *
1202  * Note that unlike add_task(), but like the 'fail' callback of
1203  * Cgu::Thread::Future objects, if a fail callback is provided to
1204  * this method and it executes, it will execute in the glib main loop
1205  * whose GMainContext object is passed to the 'context' argument of
1206  * this method.
1207  *
1208  * Note also that if releasers are provided for the 'when' or 'fail'
1209  * callbacks, these are passed by pointer and not by reference (this
1210  * is so that a NULL pointer can indicate that no releaser is to be
1211  * provided). If provided, a releaser will enable automatic
1212  * disconnection of the 'when' or 'fail' callback, if the object
1213  * having the callback function as a member is destroyed. For this to
1214  * be race free, the lifetime of that object must be controlled by
1215  * the thread in whose main loop the 'when' or 'fail' callback will
1216  * execute.
1217  *
1218  * The make_task_when() method is similar to this method but provides
1219  * an abbreviated set of paramaters suitable for most cases. This
1220  * method is for use where releasers or a 'fail' callback are
1221  * required.
1222  *
1223  * @param when A callback which will be executed if and when the
1224  * function passed to this method finishes correctly. The callback is
1225  * passed that function's return value when it is invoked. It will
1226  * execute in the glib main loop whose GMainContext object is passed
1227  * to the 'context' argument of this method.
1228  * @param when_releaser A pointer to a releaser object for automatic
1229  * disconnection of the 'when' callback if the object of which the
1230  * callback function is a member is destroyed. A value of
1231  * 0/NULL/nullptr indicates no releaser.
1232  * @param fail A callback which will be executed if the 'when'
1233  * callback does not execute. This would happen if the function
1234  * passed to this method exits by throwing Thread::Exit or some other
1235  * exception or the copy constructor of a non-reference argument of
1236  * that function throws, or if the 'when' callback does not execute
1237  * because the internal implementation of this wrapper throws
1238  * std::bad_alloc (which will not happen if the library has been
1239  * installed using the –with-glib-memory-slices-no-compat
1240  * configuration option: instead glib will terminate the program if
1241  * it is unable to obtain memory from the operating system). If an
1242  * exception propagates from the function represented by the 'fail'
1243  * callback, this will be consumed to protect the TaskManager object,
1244  * and a g_critical() warning will be issued. The callback will
1245  * execute in the glib main loop whose GMainContext object is passed
1246  * to the 'context' argument of this method. An empty
1247  * std::unique_ptr object indicates no 'fail' callback.
1248  * @param fail_releaser A pointer to a releaser object for automatic
1249  * disconnection of the 'fail' callback if the object of which the
1250  * callback function is a member is destroyed. A value of
1251  * 0/NULL/nullptr indicates no releaser.
1252  * @param priority The priority to be given in the main loop to the
1253  * 'when' callback or any 'fail' callback. In ascending order of
1254  * priorities, priorities are G_PRIORITY_LOW,
1255  * G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT
1256  * and G_PRIORITY_HIGH. This determines the order in which the
1257  * callback will appear in the event list in the main loop, not the
1258  * priority which the OS will adopt.
1259  * @param context The glib main context of the main loop in which the
1260  * 'when' callback or any 'fail' callback is to be executed. A value
1261  * 0/NULL/nullptr will cause the callback to be executed in the main
1262  * program loop.
1263  * @param t The object whose member function passed to this method is
1264  * to execute as a task.
1265  * @param func The member function to be executed as a task.
1266  * @param args The arguments to be passed to that member function.
1267  * @exception std::bad_alloc This exception will be thrown if memory
1268  * is exhausted and the sytem throws in that case. (On systems with
1269  * over-commit/lazy-commit combined with virtual memory (swap), it is
1270  * rarely useful to check for memory exhaustion).
1271  * @exception Cgu::Thread::TaskError This exception will be thrown if
1272  * stop_all() has previously been called. It will also be thrown if
1273  * is_error() would return true because this class's internal thread
1274  * pool loop implementation has thrown std::bad_alloc, or a thread
1275  * has failed to start correctly. (On systems with
1276  * over-commit/lazy-commit combined with virtual memory (swap), it is
1277  * rarely useful to check for memory exhaustion, but there may be
1278  * some specialized cases where the return value of is_error() is
1279  * useful.)
1280  * @note 1. This method will also throw if the copy or move
1281  * constructor of a bound argument throws.
1282  * @note 2. If a 'when_releaser' or a 'fail_releaser' argument is
1283  * provided, it is in theory possible (if memory is exhausted and the
1284  * system throws in that case) that an internal SafeEmitterArg object
1285  * will throw std::bad_alloc when emitting/executing the 'when' or
1286  * 'fail' callback in the glib main loop, with the result that the
1287  * relevant callback will not execute (instead the exception will be
1288  * consumed and a g_critical() warning will be issued). This is
1289  * rarely of any relevance because glib will abort the program if it
1290  * is itself unable to obtain memory from the operating system.
1291  * However, where it is relevant, design the program so that it is
1292  * not necessary to provide a releaser object.
1293  * @note 3. If the library is compiled using the --with-auto-ptr
1294  * configuration option, then this method uses std::auto_ptr in place
1295  * of std::unique_ptr in its signature in order to retain
1296  * compatibility with the 1.2 series of the library.
1297  *
1298  * Since 2.0.13
1299  */
1300  template <class Ret, class... Params, class... Args, class T>
1301 #ifdef CGU_USE_AUTO_PTR
1302  void make_task_when_full(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1303  Cgu::Releaser* when_releaser,
1304  std::auto_ptr<const Cgu::Callback::Callback> fail,
1305  Cgu::Releaser* fail_releaser,
1306  gint priority,
1307  GMainContext* context,
1308  const T& t,
1309  Ret (T::*func)(Params...) const,
1310  Args&&... args);
1311 #else
1312  void make_task_when_full(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1313  Cgu::Releaser* when_releaser,
1314  std::unique_ptr<const Cgu::Callback::Callback> fail,
1315  Cgu::Releaser* fail_releaser,
1316  gint priority,
1317  GMainContext* context,
1318  const T& t,
1319  Ret (T::*func)(Params...) const,
1320  Args&&... args);
1321 #endif
1322 
1323  /**
1324  * This is an abbreviated version of make_task_when_full(), which is
1325  * for use when it is known that the member function passed to this
1326  * method, and the copy constructors of any non-reference bound
1327  * arguments passed to it, do not throw, and the user is not
1328  * interested in std::bad_alloc and does not need a Cgu::Releaser
1329  * object for the 'when' callback (which is likely to cover the
1330  * majority of uses, particularly when composing tasks using glib
1331  * because glib terminates the program if it is unable to obtain
1332  * memory).
1333  *
1334  * This method can take up to three bound arguments for the target
1335  * member function.
1336  *
1337  * Like make_task_when_full(), this method is a wrapper which will
1338  * take a member function pointer to a member function which returns
1339  * a value, together with arguments, and constructs a TaskManager
1340  * task which will execute that function by calling add_task() with
1341  * an appropriate callback object, and causes the 'when' callback
1342  * passed as an argument to this method to be executed by a glib main
1343  * loop if and when the task finishes correctly - the 'when' callback
1344  * is passed the member function's return value when it is invoked.
1345  * It is thread safe (any thread may call this method, including
1346  * another task running on the TaskManager object). Apart from the
1347  * absence of a 'one thread per task' model, this method therefore
1348  * provides a similar interface to the one provided by
1349  * Cgu::Thread::Future. See the documentation on add_task() for
1350  * further information about how task execution works.
1351  *
1352  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
1353  * in the main loop.
1354  *
1355  * @param when A callback which will be executed if and when the
1356  * function passed to this method finishes correctly. The callback is
1357  * passed that function's return value when it is invoked. It will
1358  * execute in the glib main loop whose GMainContext object is passed
1359  * to the 'context' argument of this method.
1360  * @param context The glib main context of the main loop in which the
1361  * 'when' callback is to be executed. A value 0/NULL/nullptr will
1362  * cause the callback to be executed in the main program loop.
1363  * @param t The object whose member function passed to this method is
1364  * to execute as a task.
1365  * @param func The member function to be executed as a task.
1366  * @param args The arguments to be passed to that member function.
1367  * @exception std::bad_alloc This exception will be thrown if memory
1368  * is exhausted and the sytem throws in that case. (On systems with
1369  * over-commit/lazy-commit combined with virtual memory (swap), it is
1370  * rarely useful to check for memory exhaustion).
1371  * @exception Cgu::Thread::TaskError This exception will be thrown if
1372  * stop_all() has previously been called. It will also be thrown if
1373  * is_error() would return true because this class's internal thread
1374  * pool loop implementation has thrown std::bad_alloc, or a thread
1375  * has failed to start correctly. (On systems with
1376  * over-commit/lazy-commit combined with virtual memory (swap), it is
1377  * rarely useful to check for memory exhaustion, but there may be
1378  * some specialized cases where the return value of is_error() is
1379  * useful.)
1380  * @note 1. This method will also throw if the copy or move constructor
1381  * of a bound argument throws.
1382  * @note 2. If the library is compiled using the --with-auto-ptr
1383  * configuration option, then this method uses std::auto_ptr in place
1384  * of std::unique_ptr in its signature in order to retain
1385  * compatibility with the 1.2 series of the library.
1386  *
1387  * Since 2.0.13
1388  */
1389  template <class Ret, class... Params, class... Args, class T>
1390 #ifdef CGU_USE_AUTO_PTR
1391  void make_task_when(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1392  GMainContext* context,
1393  const T& t,
1394  Ret (T::*func)(Params...) const,
1395  Args&&... args) {
1396  static_assert(sizeof...(Args) < 4,
1397  "No greater than three bound arguments can be passed to "
1398  "TaskManager::make_task_when() taking a member function.");
1399 
1400  make_task_when_full(when,
1401  0,
1402  std::auto_ptr<const Cgu::Callback::Callback>(),
1403  0,
1404  G_PRIORITY_DEFAULT,
1405  context,
1406  t,
1407  func,
1408  std::forward<Args>(args)...);
1409  }
1410 #else
1411  void make_task_when(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1412  GMainContext* context,
1413  const T& t,
1414  Ret (T::*func)(Params...) const,
1415  Args&&... args) {
1416  static_assert(sizeof...(Args) < 4,
1417  "No greater than three bound arguments can be passed to "
1418  "TaskManager::make_task_when() taking a member function.");
1419 
1420  make_task_when_full(std::move(when),
1421  0,
1422  std::unique_ptr<const Cgu::Callback::Callback>(),
1423  0,
1424  G_PRIORITY_DEFAULT,
1425  context,
1426  t,
1427  func,
1428  std::forward<Args>(args)...);
1429  }
1430 #endif
1431 
1432  /**
1433  * This is a wrapper which will take a pointer to a function which
1434  * returns a value, together with arguments, and constructs a
1435  * TaskManager task which will execute that function by calling
1436  * add_task() with an appropriate callback object, and returns a
1437  * Cgu::AsyncResult object (held by Cgu::SharedLockPtr) which will
1438  * provide the value that the function returns. It is thread safe
1439  * (any thread may call this method, including another task running
1440  * on the TaskManager object). Apart from the absence of a 'one
1441  * thread per task' model, this method therefore provides a similar
1442  * interface to the one provided by Cgu::Thread::Future. See the
1443  * documentation on add_task() for further information about how task
1444  * execution works.
1445  *
1446  * This method can take up to four bound arguments for the target
1447  * function.
1448  *
1449  * If the function passed to this method exits by throwing
1450  * Thread::Exit or some other exception, then the returned
1451  * Cgu::AsyncResult object's get() method will unblock and its
1452  * get_error() method will return -1.
1453  *
1454  * @param func The function to be executed as a task.
1455  * @param args The arguments to be passed to that function.
1456  * @exception std::bad_alloc This exception will be thrown if memory
1457  * is exhausted and the sytem throws in that case. (On systems with
1458  * over-commit/lazy-commit combined with virtual memory (swap), it is
1459  * rarely useful to check for memory exhaustion).
1460  * @exception Cgu::Thread::TaskError This exception will be thrown if
1461  * stop_all() has previously been called. It will also be thrown if
1462  * is_error() would return true because this class's internal thread
1463  * pool loop implementation has thrown std::bad_alloc, or a thread
1464  * has failed to start correctly. (On systems with
1465  * over-commit/lazy-commit combined with virtual memory (swap), it is
1466  * rarely useful to check for memory exhaustion, but there may be
1467  * some specialized cases where the return value of is_error() is
1468  * useful.)
1469  * @note This method will also throw if the copy or move constructor
1470  * of a bound argument throws.
1471  *
1472  * Since 2.0.13
1473  */
1474  template <class Ret, class... Params, class... Args>
1476  Args&&... args);
1477 
1478  /**
1479  * This is a wrapper which will take a pointer to a function which
1480  * returns a value, together with arguments, and constructs a
1481  * TaskManager task which will execute that function by calling
1482  * add_task() with an appropriate callback object, and causes the
1483  * 'when' callback passed as an argument to this method to be
1484  * executed by a glib main loop if and when the task finishes
1485  * correctly - the 'when' callback is passed the function's return
1486  * value when it is invoked. It is thread safe (any thread may call
1487  * this method, including another task running on the TaskManager
1488  * object). Apart from the absence of a 'one thread per task' model,
1489  * this method therefore provides a similar interface to the one
1490  * provided by Cgu::Thread::Future. See the documentation on
1491  * add_task() for further information about how task execution works.
1492  *
1493  * This method can take up to four bound arguments for the target
1494  * function.
1495  *
1496  * Note that unlike add_task(), but like the 'fail' callback of
1497  * Cgu::Thread::Future objects, if a fail callback is provided to
1498  * this method and it executes, it will execute in the glib main loop
1499  * whose GMainContext object is passed to the 'context' argument of
1500  * this method.
1501  *
1502  * Note also that if releasers are provided for the 'when' or 'fail'
1503  * callbacks, these are passed by pointer and not by reference (this
1504  * is so that a NULL pointer can indicate that no releaser is to be
1505  * provided). If provided, a releaser will enable automatic
1506  * disconnection of the 'when' or 'fail' callback, if the object of
1507  * which the releaser is a member is destroyed. For this to be race
1508  * free, the lifetime of that object must be controlled by the thread
1509  * in whose main loop the 'when' or 'fail' callback will execute.
1510  *
1511  * The make_task_when() method is similar to this method but provides
1512  * an abbreviated set of paramaters suitable for most cases. This
1513  * method is for use where releasers or a 'fail' callback are
1514  * required.
1515  *
1516  * @param when A callback which will be executed if and when the
1517  * function passed to this method finishes correctly. The callback is
1518  * passed that function's return value when it is invoked. It will
1519  * execute in the glib main loop whose GMainContext object is passed
1520  * to the 'context' argument of this method.
1521  * @param when_releaser A pointer to a releaser object for automatic
1522  * disconnection of the 'when' callback if the object of which the
1523  * releaser object is a member is destroyed. A value of
1524  * 0/NULL/nullptr indicates no releaser.
1525  * @param fail A callback which will be executed if the 'when'
1526  * callback does not execute. This would happen if the function
1527  * passed to this method exits by throwing Thread::Exit or some other
1528  * exception or the copy constructor of a non-reference argument of
1529  * that function throws, or if the 'when' callback does not execute
1530  * because the internal implementation of this wrapper throws
1531  * std::bad_alloc (which will not happen if the library has been
1532  * installed using the –with-glib-memory-slices-no-compat
1533  * configuration option: instead glib will terminate the program if
1534  * it is unable to obtain memory from the operating system). If an
1535  * exception propagates from the function represented by the 'fail'
1536  * callback, this will be consumed to protect the TaskManager object,
1537  * and a g_critical() warning will be issued. The callback will
1538  * execute in the glib main loop whose GMainContext object is passed
1539  * to the 'context' argument of this method. An empty
1540  * std::unique_ptr object indicates no 'fail' callback.
1541  * @param fail_releaser A pointer to a releaser object for automatic
1542  * disconnection of the 'fail' callback if the object of which the
1543  * releaser object is a member is destroyed. A value of
1544  * 0/NULL/nullptr indicates no releaser.
1545  * @param priority The priority to be given in the main loop to the
1546  * 'when' callback or any 'fail' callback. In ascending order of
1547  * priorities, priorities are G_PRIORITY_LOW,
1548  * G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT
1549  * and G_PRIORITY_HIGH. This determines the order in which the
1550  * callback will appear in the event list in the main loop, not the
1551  * priority which the OS will adopt.
1552  * @param context The glib main context of the main loop in which the
1553  * 'when' callback or any 'fail' callback is to be executed. A value
1554  * 0/NULL/nullptr will cause the callback to be executed in the main
1555  * program loop.
1556  * @param func The function to be executed as a task.
1557  * @param args The arguments to be passed to that function.
1558  * @exception std::bad_alloc This exception will be thrown if memory
1559  * is exhausted and the sytem throws in that case. (On systems with
1560  * over-commit/lazy-commit combined with virtual memory (swap), it is
1561  * rarely useful to check for memory exhaustion).
1562  * @exception Cgu::Thread::TaskError This exception will be thrown if
1563  * stop_all() has previously been called. It will also be thrown if
1564  * is_error() would return true because this class's internal thread
1565  * pool loop implementation has thrown std::bad_alloc, or a thread
1566  * has failed to start correctly. (On systems with
1567  * over-commit/lazy-commit combined with virtual memory (swap), it is
1568  * rarely useful to check for memory exhaustion, but there may be
1569  * some specialized cases where the return value of is_error() is
1570  * useful.)
1571  * @note 1. This method will also throw if the copy or move
1572  * constructor of a bound argument throws.
1573  * @note 2. If a 'when_releaser' or a 'fail_releaser' argument is
1574  * provided, it is in theory possible (if memory is exhausted and the
1575  * system throws in that case) that an internal SafeEmitterArg object
1576  * will throw std::bad_alloc when emitting/executing the 'when' or
1577  * 'fail' callback in the glib main loop, with the result that the
1578  * relevant callback will not execute (instead the exception will be
1579  * consumed and a g_critical() warning will be issued). This is
1580  * rarely of any relevance because glib will abort the program if it
1581  * is itself unable to obtain memory from the operating system.
1582  * However, where it is relevant, design the program so that it is
1583  * not necessary to provide a releaser object.
1584  * @note 3. If the library is compiled using the --with-auto-ptr
1585  * configuration option, then this method uses std::auto_ptr in place
1586  * of std::unique_ptr in its signature in order to retain
1587  * compatibility with the 1.2 series of the library.
1588  *
1589  * Since 2.0.13
1590  */
1591  template <class Ret, class... Params, class... Args>
1592 #ifdef CGU_USE_AUTO_PTR
1593  void make_task_when_full(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1594  Cgu::Releaser* when_releaser,
1595  std::auto_ptr<const Cgu::Callback::Callback> fail,
1596  Cgu::Releaser* fail_releaser,
1597  gint priority,
1598  GMainContext* context,
1599  Ret (*func)(Params...),
1600  Args&&... args);
1601 #else
1602  void make_task_when_full(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1603  Cgu::Releaser* when_releaser,
1604  std::unique_ptr<const Cgu::Callback::Callback> fail,
1605  Cgu::Releaser* fail_releaser,
1606  gint priority,
1607  GMainContext* context,
1608  Ret (*func)(Params...),
1609  Args&&... args);
1610 #endif
1611 
1612  /**
1613  * This is an abbreviated version of make_task_when_full(), which is
1614  * for use when it is known that the function passed to this method,
1615  * and the copy constructors of any non-reference bound arguments
1616  * passed to it, do not throw, and the user is not interested in
1617  * std::bad_alloc and does not need a Cgu::Releaser object for the
1618  * 'when' callback (which is likely to cover the majority of uses,
1619  * particularly when composing tasks using glib because glib
1620  * terminates the program if it is unable to obtain memory).
1621  *
1622  * This method can take up to four bound arguments for the target
1623  * function.
1624  *
1625  * Like make_task_when_full(), this method is a wrapper which will
1626  * take a pointer to a function which returns a value, together with
1627  * arguments, and constructs a TaskManager task which will execute
1628  * that function by calling add_task() with an appropriate callback
1629  * object, and causes the 'when' callback passed as an argument to
1630  * this method to be executed by a glib main loop if and when the
1631  * task finishes correctly - the 'when' callback is passed the
1632  * function's return value when it is invoked. It is thread safe
1633  * (any thread may call this method, including another task running
1634  * on the TaskManager object). Apart from the absence of a 'one
1635  * thread per task' model, this method therefore provides a similar
1636  * interface to the one provided by Cgu::Thread::Future. See the
1637  * documentation on add_task() for further information about how task
1638  * execution works.
1639  *
1640  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
1641  * in the main loop.
1642  *
1643  * @param when A callback which will be executed if and when the
1644  * function passed to this method finishes correctly. The callback is
1645  * passed that function's return value when it is invoked. It will
1646  * execute in the glib main loop whose GMainContext object is passed
1647  * to the 'context' argument of this method.
1648  * @param context The glib main context of the main loop in which the
1649  * 'when' callback is to be executed. A value 0/NULL/nullptr will
1650  * cause the callback to be executed in the main program loop.
1651  * @param func The function to be executed as a task.
1652  * @param args The arguments to be passed to that function.
1653  * @exception std::bad_alloc This exception will be thrown if memory
1654  * is exhausted and the sytem throws in that case. (On systems with
1655  * over-commit/lazy-commit combined with virtual memory (swap), it is
1656  * rarely useful to check for memory exhaustion).
1657  * @exception Cgu::Thread::TaskError This exception will be thrown if
1658  * stop_all() has previously been called. It will also be thrown if
1659  * is_error() would return true because this class's internal thread
1660  * pool loop implementation has thrown std::bad_alloc, or a thread
1661  * has failed to start correctly. (On systems with
1662  * over-commit/lazy-commit combined with virtual memory (swap), it is
1663  * rarely useful to check for memory exhaustion, but there may be
1664  * some specialized cases where the return value of is_error() is
1665  * useful.)
1666  * @note 1. This method will also throw if the copy or move constructor
1667  * of a bound argument throws.
1668  * @note 2. If the library is compiled using the --with-auto-ptr
1669  * configuration option, then this method uses std::auto_ptr in place
1670  * of std::unique_ptr in its signature in order to retain
1671  * compatibility with the 1.2 series of the library.
1672  *
1673  * Since 2.0.13
1674  */
1675  template <class Ret, class... Params, class... Args>
1676 #ifdef CGU_USE_AUTO_PTR
1677  void make_task_when(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1678  GMainContext* context,
1679  Ret (*func)(Params...),
1680  Args&&... args) {
1681  static_assert(sizeof...(Args) < 5,
1682  "No greater than four bound arguments can be passed to "
1683  "TaskManager::make_task_when() taking a function.");
1684 
1685  make_task_when_full(when,
1686  0,
1687  std::auto_ptr<const Cgu::Callback::Callback>(),
1688  0,
1689  G_PRIORITY_DEFAULT,
1690  context,
1691  func,
1692  std::forward<Args>(args)...);
1693 #else
1694  void make_task_when(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1695  GMainContext* context,
1696  Ret (*func)(Params...),
1697  Args&&... args) {
1698  static_assert(sizeof...(Args) < 5,
1699  "No greater than four bound arguments can be passed to "
1700  "TaskManager::make_task_when() taking a function.");
1701 
1702  make_task_when_full(std::move(when),
1703  0,
1704  std::unique_ptr<const Cgu::Callback::Callback>(),
1705  0,
1706  G_PRIORITY_DEFAULT,
1707  context,
1708  func,
1709  std::forward<Args>(args)...);
1710 #endif
1711  }
1712 
1713  /**
1714  * This is a wrapper which will take a callable object (such as a
1715  * std::function object, a lambda or the return value of std::bind)
1716  * representing a function which returns a value, and constructs a
1717  * TaskManager task which will execute that function by calling
1718  * add_task() with an appropriate callback object, and returns a
1719  * Cgu::AsyncResult object (held by Cgu::SharedLockPtr) which will
1720  * provide the value that the function returns. It is thread safe
1721  * (any thread may call this method, including another task running
1722  * on the TaskManager object). Apart from the absence of a 'one
1723  * thread per task' model, this method therefore provides a similar
1724  * interface to the one provided by Cgu::Thread::Future. See the
1725  * documentation on add_task() for further information about how task
1726  * execution works.
1727  *
1728  * From version 2.0.14, this method takes the callable object as a
1729  * template parameter, and in version 2.0.13 it took it as a
1730  * std::function object. In version 2.0.13 it was necessary to
1731  * specify the return value of any callable object which was not a
1732  * std::function object as a specific template parameter: this is not
1733  * necessary in version 2.0.14, as it is deduced automatically.
1734  *
1735  * If the function passed to this method exits by throwing
1736  * Thread::Exit or some other exception, then the returned
1737  * Cgu::AsyncResult object's get() method will unblock and its
1738  * get_error() method will return -1.
1739  *
1740  * @param f The callable object to be executed as a task.
1741  * @exception std::bad_alloc This exception will be thrown if memory
1742  * is exhausted and the sytem throws in that case. (On systems with
1743  * over-commit/lazy-commit combined with virtual memory (swap), it is
1744  * rarely useful to check for memory exhaustion).
1745  * @exception Cgu::Thread::TaskError This exception will be thrown if
1746  * stop_all() has previously been called. It will also be thrown if
1747  * is_error() would return true because this class's internal thread
1748  * pool loop implementation has thrown std::bad_alloc, or a thread
1749  * has failed to start correctly. (On systems with
1750  * over-commit/lazy-commit combined with virtual memory (swap), it is
1751  * rarely useful to check for memory exhaustion, but there may be
1752  * some specialized cases where the return value of is_error() is
1753  * useful.)
1754  * @note 1. This method will also throw if the copy or move
1755  * constructor of the callable object throws.
1756  * @note 2. If the callable object passed as an argument has both
1757  * const and non-const operator()() methods, the non-const version
1758  * will be called even if the callable object passed is a const
1759  * object.
1760  *
1761  * Since 2.0.13
1762  */
1763  // we don't need this version of make_task_result() for syntactic
1764  // reasons - the version taking a single template parameter will do
1765  // by itself syntactically because it can use decltype. However, we
1766  // include this version in order to be API compatible with
1767  // c++-gtk-utils < 2.0.14, which required the return type to be
1768  // specified when this method is passed something other than a
1769  // std::function object. SFINAE will take care of the rest, except
1770  // with a corner case where all of the following apply: (i) a
1771  // function object is passed whose operator()() method returns a
1772  // copy of the function object (or another function object of the
1773  // same type), (ii) the function object is passed to this method as
1774  // a rvalue and not a lvalue, and (iii) the user specifically states
1775  // the return type when instantiating this template function. This
1776  // would give rise to an ambiguity, but its happening is extremely
1777  // unlikely, and cannot happen with a lambda or the return value of
1778  // std::bind, because those types are only known to the compiler,
1779  // and cannot happen with other objects if the user lets template
1780  // deduction take its course.
1781  template <class Ret, class Func>
1783 
1784  // we don't want to document this function: it provides the type
1785  // deduction of the return value of the passed functor (it deals
1786  // with cases where this is not specified expressly).
1787 #ifndef DOXYGEN_PARSING
1788  template <class Func>
1790 
1791  // TODO: this is a work-around for gcc < 4.7, which has a bug
1792  // which requires a function whose return value is determined by
1793  // decltype, such as make_task_result(Func&&), to be inline. At a
1794  // suitable API/ABI break when gcc requirements are updated, this
1795  // should be moved to task_manager.tpp.
1796 
1797  // there are two types related to the functor to be executed by
1798  // the task. 'Func' is the transient type provided by argument
1799  // deduction for forwarding, and will vary depending on whether
1800  // the functor object is a lvalue (which will deduce it as a
1801  // reference type) or rvalue (which will not). 'FType' is the
1802  // type to be held by the callback object generated in this
1803  // function, and is never a reference type. It is also never
1804  // const, because the FType member is marked mutable in the
1805  // callback object so that it can execute mutable lambdas (or
1806  // other functors with a non-const operator()() method).
1807  typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
1808  typedef decltype(f()) Ret;
1809 #ifdef CGU_USE_AUTO_PTR
1810  typedef std::auto_ptr<const Callback::Callback> CbPtr;
1811 #else
1812  typedef std::unique_ptr<const Callback::Callback> CbPtr;
1813 #endif
1814 
1816  CbPtr exec_cb(new TaskManagerHelper::FunctorResultExec<Ret, FType>(std::forward<Func>(f), ret));
1817  CbPtr do_fail_cb(Callback::make_ref(&TaskManagerHelper::FunctorResultWrapper<Ret, FType>::do_fail,
1818  ret));
1819  add_task(std::move(exec_cb), std::move(do_fail_cb));
1820 
1821  return ret;
1822  }
1823 #endif
1824 
1825  /**
1826  * This is a wrapper which will take a callable object (such as a
1827  * std::function object, a lambda or the return value of std::bind)
1828  * representing a function which returns a value, and constructs a
1829  * TaskManager task which will execute that function by calling
1830  * add_task() with an appropriate callback object, and causes the
1831  * 'when' callback passed as an argument to this method to be
1832  * executed by a glib main loop if and when the task finishes
1833  * correctly - the 'when' callback is passed the function's return
1834  * value when it is invoked. It is thread safe (any thread may call
1835  * this method, including another task running on the TaskManager
1836  * object). Apart from the absence of a 'one thread per task' model,
1837  * this method therefore provides a similar interface to the one
1838  * provided by Cgu::Thread::Future. See the documentation on
1839  * add_task() for further information about how task execution works.
1840  *
1841  * From version 2.0.14, this method takes the callable object as a
1842  * template parameter, and in version 2.0.13 it took it as a
1843  * std::function object. In version 2.0.13 it was necessary to
1844  * specify the return value of any callable object which was not a
1845  * std::function object as a specific template parameter: this is not
1846  * necessary in version 2.0.14, as it is deduced automatically.
1847  *
1848  * Note that unlike add_task(), but like the 'fail' callback of
1849  * Cgu::Thread::Future objects, if a fail callback is provided to
1850  * this method and it executes, it will execute in the glib main loop
1851  * whose GMainContext object is passed to the 'context' argument of
1852  * this method.
1853  *
1854  * Note also that if releasers are provided for the 'when' or 'fail'
1855  * callbacks, these are passed by pointer and not by reference (this
1856  * is so that a NULL pointer can indicate that no releaser is to be
1857  * provided). If provided, a releaser will enable automatic
1858  * disconnection of the 'when' or 'fail' callback, if the object of
1859  * which the releaser is a member is destroyed. For this to be race
1860  * free, the lifetime of that object must be controlled by the thread
1861  * in whose main loop the 'when' or 'fail' callback will execute.
1862  *
1863  * The make_task_when() method is similar to this method but provides
1864  * an abbreviated set of paramaters suitable for most cases. This
1865  * method is for use where releasers or a 'fail' callback are
1866  * required.
1867  *
1868  * @param when A callback which will be executed if and when the
1869  * function represented by the callable object passed to this method
1870  * finishes correctly. The callback is passed that function's return
1871  * value when it is invoked. It will execute in the glib main loop
1872  * whose GMainContext object is passed to the 'context' argument of
1873  * this method.
1874  * @param when_releaser A pointer to a releaser object for automatic
1875  * disconnection of the 'when' callback if the object of which the
1876  * releaser object is a member is destroyed. A value of
1877  * 0/NULL/nullptr indicates no releaser.
1878  * @param fail A callback which will be executed if the 'when'
1879  * callback does not execute. This would happen if the function
1880  * represented by the std::function object passed to this method
1881  * exits by throwing Thread::Exit or some other exception or the copy
1882  * constructor of a non-reference argument of that function throws,
1883  * or if the 'when' callback does not execute because the internal
1884  * implementation of this wrapper throws std::bad_alloc (which will
1885  * not happen if the library has been installed using the
1886  * –with-glib-memory-slices-no-compat configuration option: instead
1887  * glib will terminate the program if it is unable to obtain memory
1888  * from the operating system). If an exception propagates from the
1889  * function represented by the 'fail' callback, this will be consumed
1890  * to protect the TaskManager object, and a g_critical() warning will
1891  * be issued. The callback will execute in the glib main loop whose
1892  * GMainContext object is passed to the 'context' argument of this
1893  * method. An empty std::unique_ptr object indicates no 'fail'
1894  * callback.
1895  * @param fail_releaser A pointer to a releaser object for automatic
1896  * disconnection of the 'fail' callback if the object of which the
1897  * releaser object is a member is destroyed. A value of
1898  * 0/NULL/nullptr indicates no releaser.
1899  * @param priority The priority to be given in the main loop to the
1900  * 'when' callback or any 'fail' callback. In ascending order of
1901  * priorities, priorities are G_PRIORITY_LOW,
1902  * G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT
1903  * and G_PRIORITY_HIGH. This determines the order in which the
1904  * callback will appear in the event list in the main loop, not the
1905  * priority which the OS will adopt.
1906  * @param context The glib main context of the main loop in which the
1907  * 'when' callback or any 'fail' callback is to be executed. A value
1908  * 0/NULL/nullptr will cause the callback to be executed in the main
1909  * program loop.
1910  * @param f The callable object to be executed as a task.
1911  * @exception std::bad_alloc This exception will be thrown if memory
1912  * is exhausted and the sytem throws in that case. (On systems with
1913  * over-commit/lazy-commit combined with virtual memory (swap), it is
1914  * rarely useful to check for memory exhaustion).
1915  * @exception Cgu::Thread::TaskError This exception will be thrown if
1916  * stop_all() has previously been called. It will also be thrown if
1917  * is_error() would return true because this class's internal thread
1918  * pool loop implementation has thrown std::bad_alloc, or a thread
1919  * has failed to start correctly. (On systems with
1920  * over-commit/lazy-commit combined with virtual memory (swap), it is
1921  * rarely useful to check for memory exhaustion, but there may be
1922  * some specialized cases where the return value of is_error() is
1923  * useful.)
1924  * @note 1. This method will also throw if the copy or move
1925  * constructor of the callable object throws.
1926  * @note 2. If the callable object passed as an argument has both
1927  * const and non-const operator()() methods, the non-const version
1928  * will be called even if the callable object passed is a const
1929  * object.
1930  * @note 3. If a 'when_releaser' or a 'fail_releaser' argument is
1931  * provided, it is in theory possible (if memory is exhausted and the
1932  * system throws in that case) that an internal SafeEmitterArg object
1933  * will throw std::bad_alloc when emitting/executing the 'when' or
1934  * 'fail' callback in the glib main loop, with the result that the
1935  * relevant callback will not execute (instead the exception will be
1936  * consumed and a g_critical() warning will be issued). This is
1937  * rarely of any relevance because glib will abort the program if it
1938  * is itself unable to obtain memory from the operating system.
1939  * However, where it is relevant, design the program so that it is
1940  * not necessary to provide a releaser object.
1941  * @note 4. If the library is compiled using the --with-auto-ptr
1942  * configuration option, then this method uses std::auto_ptr in place
1943  * of std::unique_ptr in its signature in order to retain
1944  * compatibility with the 1.2 series of the library.
1945  *
1946  * Since 2.0.13
1947  */
1948  template <class Ret, class Func>
1949 #ifdef CGU_USE_AUTO_PTR
1950  void make_task_when_full(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1951  Cgu::Releaser* when_releaser,
1952  std::auto_ptr<const Cgu::Callback::Callback> fail,
1953  Cgu::Releaser* fail_releaser,
1954  gint priority,
1955  GMainContext* context,
1956  Func&& f);
1957 #else
1958  void make_task_when_full(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1959  Cgu::Releaser* when_releaser,
1960  std::unique_ptr<const Cgu::Callback::Callback> fail,
1961  Cgu::Releaser* fail_releaser,
1962  gint priority,
1963  GMainContext* context,
1964  Func&& f);
1965 #endif
1966 
1967  /**
1968  * This is an abbreviated version of make_task_when_full(), which is
1969  * for use when it is known that the function represented by the
1970  * callable object passed to this method, and the copy constructors
1971  * of any non-reference bound arguments passed to it, do not throw,
1972  * and the user is not interested in std::bad_alloc and does not need
1973  * a Cgu::Releaser object for the 'when' callback (which is likely to
1974  * cover the majority of uses, particularly when composing tasks
1975  * using glib because glib terminates the program if it is unable to
1976  * obtain memory).
1977  *
1978  * From version 2.0.14, this method takes the callable object as a
1979  * template parameter, and in version 2.0.13 it took it as a
1980  * std::function object. In version 2.0.13 it was necessary to
1981  * specify the return value of any callable object which was not a
1982  * std::function object as a specific template parameter: this is not
1983  * necessary in version 2.0.14, as it is deduced automatically.
1984  *
1985  * Like make_task_when_full(), this method is a wrapper which will
1986  * take a callable object representing a function which returns a
1987  * value, and constructs a TaskManager task which will execute that
1988  * function by calling add_task() with an appropriate callback
1989  * object, and causes the 'when' callback passed as an argument to
1990  * this method to be executed by a glib main loop if and when the
1991  * task finishes correctly - the 'when' callback is passed the
1992  * function's return value when it is invoked. It is thread safe
1993  * (any thread may call this method, including another task running
1994  * on the TaskManager object). Apart from the absence of a 'one
1995  * thread per task' model, this method therefore provides a similar
1996  * interface to the one provided by Cgu::Thread::Future. See the
1997  * documentation on add_task() for further information about how task
1998  * execution works.
1999  *
2000  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
2001  * in the main loop.
2002  *
2003  * There is a similar make_task_compose() function which has the
2004  * callable object to be executed as a task as its first argument and
2005  * the 'when' callback as its last argument, in order to aid task
2006  * composition.
2007  *
2008  * @param when A callback which will be executed if and when the
2009  * function represented by the callable object passed to this method
2010  * finishes correctly. The callback is passed that function's return
2011  * value when it is invoked. It will execute in the glib main loop
2012  * whose GMainContext object is passed to the 'context' argument of
2013  * this method.
2014  * @param context The glib main context of the main loop in which the
2015  * 'when' callback is to be executed. A value 0/NULL/nullptr will
2016  * cause the callback to be executed in the main program loop.
2017  * @param f The callable object to be executed as a task.
2018  * @exception std::bad_alloc This exception will be thrown if memory
2019  * is exhausted and the sytem throws in that case. (On systems with
2020  * over-commit/lazy-commit combined with virtual memory (swap), it is
2021  * rarely useful to check for memory exhaustion).
2022  * @exception Cgu::Thread::TaskError This exception will be thrown if
2023  * stop_all() has previously been called. It will also be thrown if
2024  * is_error() would return true because this class's internal thread
2025  * pool loop implementation has thrown std::bad_alloc, or a thread
2026  * has failed to start correctly. (On systems with
2027  * over-commit/lazy-commit combined with virtual memory (swap), it is
2028  * rarely useful to check for memory exhaustion, but there may be
2029  * some specialized cases where the return value of is_error() is
2030  * useful.)
2031  * @note 1. This method will also throw if the copy or move
2032  * constructor of the callable object throws.
2033  * @note 2. If the callable object passed as an argument has both
2034  * const and non-const operator()() methods, the non-const version
2035  * will be called even if the callable object passed is a const
2036  * object.
2037  * @note 3. If the library is compiled using the --with-auto-ptr
2038  * configuration option, then this method uses std::auto_ptr in place
2039  * of std::unique_ptr in its signature in order to retain
2040  * compatibility with the 1.2 series of the library.
2041  *
2042  * Since 2.0.13
2043  */
2044  template <class Ret, class Func>
2045 #ifdef CGU_USE_AUTO_PTR
2046  void make_task_when(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
2047  GMainContext* context,
2048  Func&& f) {
2049  make_task_when_full(when,
2050  0,
2051  std::auto_ptr<const Cgu::Callback::Callback>(),
2052  0,
2053  G_PRIORITY_DEFAULT,
2054  context,
2055  std::forward<Func>(f));
2056  }
2057 #else
2058  void make_task_when(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
2059  GMainContext* context,
2060  Func&& f) {
2061  make_task_when_full(std::move(when),
2062  0,
2063  std::unique_ptr<const Cgu::Callback::Callback>(),
2064  0,
2065  G_PRIORITY_DEFAULT,
2066  context,
2067  std::forward<Func>(f));
2068  }
2069 #endif
2070 
2071  /**
2072  * This is an abbreviated version of make_task_when_full(), which is
2073  * for use when it is known that the function represented by the
2074  * callable object passed to this method, and the copy
2075  * constructors of any non-reference bound arguments passed to it, do
2076  * not throw, and the user is not interested in std::bad_alloc and
2077  * does not need a Cgu::Releaser object for the 'when' callback
2078  * (which is likely to cover the majority of uses, particularly when
2079  * composing tasks using glib because glib terminates the program if
2080  * it is unable to obtain memory).
2081  *
2082  * From version 2.0.14, this method takes the callable object as a
2083  * template parameter, and in version 2.0.13 it took it as a
2084  * std::function object. In version 2.0.13 it was necessary to
2085  * specify the return value of any callable object which was not a
2086  * std::function object as a specific template parameter: this is not
2087  * necessary in version 2.0.14, as it is deduced automatically.
2088  *
2089  * This method does the same as the version of make_task_when()
2090  * taking a function object, except that this method takes the
2091  * callable object to be executed as a task as its first argument and
2092  * the 'when' callback as its last argument in order to aid task
2093  * composition, and in particular so tasks compose in user code in a
2094  * visually ordered manner.
2095  *
2096  * More particularly, like make_task_when_full(), this method is a
2097  * wrapper which will take a callable object representing a function
2098  * which returns a value, and constructs a TaskManager task which
2099  * will execute that function by calling add_task() with an
2100  * appropriate callback object, and causes the 'when' callback passed
2101  * as an argument to this method to be executed by a glib main loop
2102  * if and when the task finishes correctly - the 'when' callback is
2103  * passed the function's return value when it is invoked. It is
2104  * thread safe (any thread may call this method, including another
2105  * task running on the TaskManager object). Apart from the absence
2106  * of a 'one thread per task' model, this method therefore provides a
2107  * similar interface to the one provided by Cgu::Thread::Future. See
2108  * the documentation on add_task() for further information about how
2109  * task execution works.
2110  *
2111  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
2112  * in the main loop.
2113  *
2114  * @param f The callable object to be executed as a task.
2115  * @param context The glib main context of the main loop in which the
2116  * 'when' callback is to be executed. A value 0/NULL/nullptr will
2117  * cause the callback to be executed in the main program loop.
2118  * @param when A callback which will be executed if and when the
2119  * function represented by the callable object passed to this method
2120  * finishes correctly. The callback is passed that function's return
2121  * value when it is invoked. It will execute in the glib main loop
2122  * whose GMainContext object is passed to the 'context' argument of
2123  * this method.
2124  * @exception std::bad_alloc This exception will be thrown if memory
2125  * is exhausted and the sytem throws in that case. (On systems with
2126  * over-commit/lazy-commit combined with virtual memory (swap), it is
2127  * rarely useful to check for memory exhaustion).
2128  * @exception Cgu::Thread::TaskError This exception will be thrown if
2129  * stop_all() has previously been called. It will also be thrown if
2130  * is_error() would return true because this class's internal thread
2131  * pool loop implementation has thrown std::bad_alloc, or a thread
2132  * has failed to start correctly. (On systems with
2133  * over-commit/lazy-commit combined with virtual memory (swap), it is
2134  * rarely useful to check for memory exhaustion, but there may be
2135  * some specialized cases where the return value of is_error() is
2136  * useful.)
2137  * @note 1. This method will also throw if the copy or move
2138  * constructor of the callable object throws.
2139  * @note 2. If the callable object passed as an argument has both
2140  * const and non-const operator()() methods, the non-const version
2141  * will be called even if the callable object passed is a const
2142  * object.
2143  * @note 3. If the library is compiled using the --with-auto-ptr
2144  * configuration option, then this method uses std::auto_ptr in place
2145  * of std::unique_ptr in its signature in order to retain
2146  * compatibility with the 1.2 series of the library.
2147  *
2148  * Since 2.0.13
2149  */
2150  template <class Ret, class Func>
2151 #ifdef CGU_USE_AUTO_PTR
2152  void make_task_compose(Func&& f,
2153  GMainContext* context,
2154  std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when) {
2155  make_task_when_full(when,
2156  0,
2157  std::auto_ptr<const Cgu::Callback::Callback>(),
2158  0,
2159  G_PRIORITY_DEFAULT,
2160  context,
2161  std::forward<Func>(f));
2162  }
2163 #else
2164  void make_task_compose(Func&& f,
2165  GMainContext* context,
2166  std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when) {
2167  make_task_when_full(std::move(when),
2168  0,
2169  std::unique_ptr<const Cgu::Callback::Callback>(),
2170  0,
2171  G_PRIORITY_DEFAULT,
2172  context,
2173  std::forward<Func>(f));
2174  }
2175 #endif
2176 
2177  /**
2178  * If the specified minimum number of threads is greater than 0, this
2179  * constructor will start the required minimum number of threads. If
2180  * glib < 2.32 is installed, g_thread_init() must be called before
2181  * any TaskManager objects are constructed
2182  * @param max The maximum number of threads which the TaskManager
2183  * object will run in the thread pool. If the value passed as this
2184  * argument is less than the value passed as 'min', the maximum
2185  * number of threads will be set to 'min'. A value of 0 is not
2186  * valid, and if this is passed the number will be set to the greater
2187  * of 1 and 'min'.
2188  * @param min The minimum number of threads which the TaskManager
2189  * object will run in the thread pool.
2190  * @param idle The length of time in milliseconds that threads
2191  * greater in number than 'min' and not executing any tasks will
2192  * remain in existence. The default is 10000 (10 seconds).
2193  * @param blocking If true, calls to stop_all() and the destructor
2194  * will not return until the tasks remaining to be executed have
2195  * finished (what is meant by "the tasks remaining to be executed"
2196  * depends on the StopMode setting, for which see the documentation
2197  * on the stop_all() method). If false, stop_all() and the
2198  * destructor will return straight away (which in terms of the
2199  * TaskManager class implementation is safe for the reasons explained
2200  * in the documentation on the destructor).
2201  * @param mode The StopMode setting (either
2202  * Cgu::Thread::TaskManager::wait_for_running or
2203  * Cgu::Thread::TaskManager::wait_for_all) executed when running
2204  * stop_all() or when the destructor is called. See the
2205  * documentation on stop_all() for an explanation of the setting.
2206  * @exception std::bad_alloc This exception might be thrown if memory
2207  * is exhausted and the system throws in that case.
2208  * @exception Cgu::Thread::TaskError This exception will be thrown if
2209  * starting the specified minimum number of threads fails.
2210  * @exception Cgu::Thread::MutexError This exception might be thrown
2211  * if initialisation of the contained mutex fails. (It is often not
2212  * worth checking for this, as it means either memory is exhausted or
2213  * pthread has run out of other resources to create new mutexes.)
2214  * @exception Cgu::Thread::CondError This exception might be thrown
2215  * if initialisation of the contained condition variable fails. (It
2216  * is often not worth checking for this, as it means either memory is
2217  * exhausted or pthread has run out of other resources to create new
2218  * condition variables.)
2219  *
2220  * Since 2.0.12
2221  */
2222  TaskManager(unsigned int max = 8, unsigned int min = 0,
2223  unsigned int idle = 10000, bool blocking = true,
2225 
2226  /**
2227  * The destructor will call stop_all(), unless that method has
2228  * previously been called explicitly without throwing std::bad_alloc.
2229  * If the blocking setting is true, the destructor will not return
2230  * until the tasks remaining to be executed have finished (what is
2231  * meant by "the tasks remaining to be executed" depends on the
2232  * StopMode setting, for which see the documentation on the
2233  * stop_all() method.) If the blocking setting is false, the
2234  * destructor will return straight away: this is safe, because
2235  * TaskManager's internals for running tasks have been implemented
2236  * using reference counting and will not be deleted until all threads
2237  * running on the TaskManager object have finished, although the
2238  * remaining tasks should not attempt to call any of TaskManager's
2239  * methods once the TaskManager object itself has been destroyed.
2240  *
2241  * The destructor is thread safe (any thread can destroy a
2242  * TaskManager object) unless the blocking setting is true, in which
2243  * case no task running on the TaskManager object may destroy the
2244  * TaskManager object. Subject to that, it is not an error for a
2245  * thread to destroy a TaskManager object and so invoke this
2246  * destructor while another thread is already blocking in (if the
2247  * blocking setting is true) or already out of (if the blocking
2248  * setting is false) a call to stop_all() and remaining tasks are
2249  * executing: if blocking, both calls (to stop_all() and to this
2250  * destructor) would safely block together. Any given thread can
2251  * similarly safely follow a non-blocking call to stop_all() by a
2252  * non-blocking call to this destructor even though remaining tasks
2253  * are executing. However, it is an error for a thread to call
2254  * stop_all() after another thread has begun destruction of the
2255  * TaskManager object (that is, after this destructor has been
2256  * entered): there would then be an unresolvable race with the
2257  * destructor.
2258  *
2259  * The destructor will not throw.
2260  *
2261  * If stop_all() has not previously been called explicitly and throws
2262  * std::bad_alloc() when called in this destructor, the exception
2263  * will be caught and consumed, but then the destructor will not
2264  * block even if the blocking setting is true, and if the minimum
2265  * number of threads is not 0 some threads might remain running
2266  * during the entire program duration (albeit safely). Where the
2267  * throwing of std::bad_alloc is a meaningful event (usually it
2268  * isn't) and needs to be guarded against, call stop_all() explicitly
2269  * before this destructor is entered, or use a minimum thread value
2270  * of 0 and allow for the case of the destructor not blocking.
2271  *
2272  * Since 2.0.12
2273  */
2274  ~TaskManager();
2275 
2276 /* Only has effect if --with-glib-memory-slices-compat or
2277  * --with-glib-memory-slices-no-compat option picked */
2279 };
2280 
2281 } // namespace Thread
2282 
2283 } // namespace Cgu
2284 
2285 #include <c++-gtk-utils/task_manager.tpp>
2286 
2287 #endif