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