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