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