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