c++-gtk-utils
task_manager.h
Go to the documentation of this file.
1 /* Copyright (C) 2012 to 2016 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::AsyncChannel 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  * Rate limiting
351  * -------------
352  *
353  * Resources are not infinite and there is a hard limit to the number
354  * of tasks that a TaskManager object may have queued for execution at
355  * any one time. From version 2.0.31 the limit to the number of
356  * running and queued tasks may be obtained by calling the
357  * TaskManager::get_max_tasks() method (note that particularly on
358  * 32-bit systems it will in practice be impossible to reach this
359  * limit because of memory exhaustion: the value returned by that
360  * method represents the limit enforced by TaskManager irrespective of
361  * the actual available memory at the system or process level and any
362  * intervention of std::bad_alloc exceptions). If that limit is
363  * exceeded, the TaskManager::add_task() and TaskManager::make_task_*
364  * methods will throw std::length_error.
365  *
366  * In practice however, on most systems such a large number of queued
367  * tasks (normally around 4,294,967,295 for 64-bit systems) is likely
368  * to be unfeasible and program logic constraints will be exceeded
369  * long before the limit is reached, even if available memory is not.
370  * In some usages therefore, some form of rate limiting may be needed
371  * to prevent a work-producing thread overwhelming a TaskManager
372  * object by continuously adding more tasks for execution than the
373  * object's throughput capacity is capable of dealing with, so pushing
374  * the number of unexecuted tasks to an excessive level.
375  *
376  * TaskManager objects provide no built-in rate limiting (other than
377  * throwing the std::length_error exception referred to above). This
378  * is because there is no one-size-fits-all way of doing so. One
379  * common approach is to apply throttling to threads which add tasks
380  * by enforcing a wait in their thread of execution when the level of
381  * queued tasks reaches too high a level, so hindering their ability
382  * to add new ones. However this is counter productive where it is a
383  * task running on the TaskManager object which is adding the new
384  * tasks, particularly with a TaskManager object having only a few
385  * threads running in its pool. Another approach is to throw an
386  * exception when adding tasks which exceed a user-selectable level
387  * which is much lower than the value returned by
388  * TaskManager::get_max_tasks(), but this would make it more difficult
389  * to use the Cgu::Thread::parallel_for_each() and
390  * Cgu::Thread::parallel_transform() functions provided by this
391  * library.
392  *
393  * The best approach is for user code to provide its own rate limiting
394  * in cases where the way that that code is organised means that it
395  * could produce an excessive number of accumulating unexecuted tasks,
396  * possibly by applying delays when unexecuted tasks rise in number
397  * excessively, using timeouts with a glib main loop. This may be
398  * checked for by having code call the TaskManager::get_tasks() method
399  * before adding a significant batch of new tasks in order to test
400  * queue size, and if necessary postpone adding the new tasks until
401  * the size of the already accumulated tasks has reduced.
402  *
403  * The Cgu::AsyncChannel class has emplace() and push() methods which
404  * will block when a channel is full. That class can therefore be
405  * used for rate limiting function objects pushed onto the channel in
406  * cases where that is an appropriate alternative solution to
407  * TaskManager.
408  */
409 
410 // TODO: this is a work-around for gcc < 4.7, which has a bug which
411 // requires a function whose return value is determined by decltype,
412 // such as make_task_result(Func&&), to be inline. At a suitable
413 // API/ABI break when gcc requirements are updated, this should be
414 // moved to task_manager.tpp.
415 namespace TaskManagerHelper2 {
416 
417 template <class Ret, class FType>
419  static void exec(FType& f,
420  const SharedLockPtr<AsyncResult<Ret>>& ret) {
421  ret->set(f());
422  }
423  static void do_fail(const SharedLockPtr<AsyncResult<Ret>>& ret) {
424  ret->set_error(); // won't throw
425  }
426 };
427 
428 /*
429  * The FunctorResultExec class is a specialised class which is
430  * necessary because the 'functor' member needs to be declared mutable
431  * so that it can bind to the reference to non-const argument of
432  * FunctorResultWrapper::exec(), and thus so that a mutable lambda can
433  * be executed by that function. Because it is so specialised, it is
434  * not suitable for inclusion in the generic interfaces provided in
435  * callback.h. (Except in this specialised usage, it can also be
436  * dangerous, as it allows a member of the callback object to be
437  * mutated: normally this would be undesirable.) An alternative would
438  * have been to put the 'functor' member in a wrapper struct like
439  * MemfunWhenWrapperArgs or FunWhenWrapperArgs, but if 'functor' were
440  * an lvalue that would mean it being copied twice. This is the most
441  * efficient implementation.
442  */
443 template <class Ret, class FType>
445  mutable FType functor;
447 public:
448  void dispatch() const {FunctorResultWrapper<Ret, FType>::exec(functor, ret);}
449  // we don't need to templatize 'ret_' for perfect forwarding - it is
450  // always passed as a lvalue
451  template <class FunctorArg>
452  FunctorResultExec(FunctorArg&& functor_,
453  const SharedLockPtr<AsyncResult<Ret>>& ret_): functor(std::forward<FunctorArg>(functor_)),
454  ret(ret_) {}
455 };
456 
457 } // namespace TaskManagerHelper2
458 
459 
460 class TaskManager {
461  public:
463  class IncHandle;
464  private:
465  typedef std::pair<std::unique_ptr<const Callback::Callback>,
466  std::unique_ptr<const Callback::Callback>> QueueItemType;
467 
468  struct RefImpl; // reference counted implementation class
469  // it is fine holding RefImpl by plain pointer and not by
470  // IntrusivePtr: it is the only data member this class has, so it
471  // can safely manage that member in its own destructor and other
472  // methods
473  RefImpl* ref_impl;
474 
475  void set_max_threads_impl(unsigned int max, Mutex::TrackLock& lock);
476  static unsigned int init_max_tasks();
477  public:
478 /**
479  * This class cannot be copied. The copy constructor is deleted.
480  */
481  TaskManager(const TaskManager&) = delete;
482 
483 /**
484  * This class cannot be copied. The assignment operator is deleted.
485  */
486  TaskManager& operator=(const TaskManager&) = delete;
487 
488  /**
489  * Gets the maximum number of threads which the TaskManager object is
490  * currently set to run in the thread pool. This value is established
491  * initially by the 'max' argument passed to the TaskManager
492  * constructor and can subequently be changed by calling
493  * set_max_threads() or change_max_threads(). The default value is 8.
494  * This method will not throw and is thread safe. However, if a
495  * blocking task might use the TaskManager::IncHandle class (or
496  * increase and then decrease the number by hand by calling
497  * change_max_threads()), this method will not usually be useful.
498  * @return The maximum number of threads.
499  *
500  * Since 2.0.12
501  */
502  unsigned int get_max_threads() const;
503 
504  /**
505  * Gets the minimum number of threads which the TaskManager object
506  * will run in the thread pool (these threads will last until
507  * stop_all() is called or the TaskManager object is destroyed).
508  * This value is established by the 'min' argument passed to the
509  * TaskManager constructor and cannot subequently be changed. The
510  * default is 0. This method will not throw and is thread safe.
511  * @return The minimum number of threads.
512  *
513  * Since 2.0.12
514  */
515  unsigned int get_min_threads() const;
516 
517  /**
518  * Gets the number of threads which the TaskManager object is
519  * currently running in the thread pool, including those blocking
520  * waiting for a task. This value could be greater than the number
521  * returned by get_max_threads() if change_max_threads() has recently
522  * been called with a negative number but not enough tasks have since
523  * completed to reduce the number of running threads to the new value
524  * set. This method will not throw and is thread safe.
525  * @return The number of threads running in the thread pool,
526  * including those blocking waiting for a task.
527  *
528  * Since 2.0.12
529  */
530  unsigned int get_used_threads() const;
531 
532  /**
533  * @deprecated
534  *
535  * DEPRECATED. Use change_max_threads() instead. This method will
536  * interfere with the intended operation of the
537  * ThreadManager::IncHandle class if one task constructs a IncHandle
538  * object and another calls this method.
539  *
540  * Sets the maximum number of threads which the TaskManager object
541  * will currently run in the thread pool. If this is less than the
542  * current number of running threads, the number of threads actually
543  * running will only be reduced as tasks complete, or as idle
544  * timeouts expire. This method does nothing if stop_all() has
545  * previously been called. This method is thread safe.
546  * @param max The maximum number of threads which the TaskManager
547  * object will currently run in the thread pool. This method will
548  * not set the maximum value of threads to a value less than that
549  * returned by get_min_threads(), nor to a value less than 1.
550  * @exception std::bad_alloc If this call is passed a value for 'max'
551  * which increases the maximum number of threads from its previous
552  * setting and tasks are currently queued for execution, new threads
553  * will be started for the queued tasks, so this exception may be
554  * thrown on starting the new threads if memory is exhausted and the
555  * system throws in that case. (On systems with
556  * over-commit/lazy-commit combined with virtual memory (swap), it is
557  * rarely useful to check for memory exhaustion).
558  * @exception Cgu::Thread::TaskError If this call is passed a value
559  * for 'max' which increases the maximum number of threads from its
560  * previous setting and tasks are currently queued for execution, new
561  * threads will be started for the queued tasks, so this exception
562  * may be thrown on starting the new threads if a thread fails to
563  * start correctly (this would mean that memory is exhausted, the
564  * pthread thread limit has been reached or pthread has run out of
565  * other resources to start new threads).
566  *
567  * Since 2.0.12
568  */
569  void set_max_threads(unsigned int max);
570 
571  /**
572  * This will increase, or if 'delta' is negative reduce, the maximum
573  * number of threads which the TaskManager object will currently run
574  * in the thread pool by the value of 'delta'. The purpose of this
575  * is to enable a task to increment the maximum thread number where
576  * it is about to enter a call which may block for some time, with a
577  * view to decrementing it later when it has finished making blocking
578  * calls, so as to enable another thread to keep a core active. If
579  * 'delta' is negative and results in a max_threads value of less
580  * than the current number of running threads, the number of threads
581  * actually running will only be reduced as tasks complete, or as
582  * idle timeouts expire. This method does nothing if stop_all() has
583  * previously been called. This method is thread safe. Since
584  * version 2.0.18, the scoped handle class TaskManager::IncHandle is
585  * available which calls this method.
586  * @param delta The change (positive or negative) to the maximum
587  * number of threads which the TaskManager object will currently run
588  * in the thread pool. This method will not set the maximum value of
589  * threads to a value less than that returned by get_min_threads(),
590  * nor to a value less than 1.
591  * @exception std::bad_alloc If this call is passed a positive value
592  * and tasks are currently queued for execution, a new thread or
593  * threads will be started for the queued tasks, so this exception
594  * may be thrown on starting a new thread if memory is exhausted and
595  * the system throws in that case. (On systems with
596  * over-commit/lazy-commit combined with virtual memory (swap), it is
597  * rarely useful to check for memory exhaustion).
598  * @exception Cgu::Thread::TaskError If this call is passed a
599  * positive value and tasks are currently queued for execution, a new
600  * thread or threads will be started for the queued tasks, so this
601  * exception may be thrown on starting a new thread if it fails to
602  * start correctly (this would mean that memory is exhausted, the
603  * pthread thread limit has been reached or pthread has run out of
604  * other resources to start new threads).
605  *
606  * Since 2.0.14
607  */
608  void change_max_threads(int delta);
609 
610  /**
611  * Gets the number of tasks which the TaskManager object is at
612  * present either running in the thread pool or has queued for
613  * execution. This value will be less than the number returned by
614  * get_used_threads() if threads in the thread pool are currently
615  * waiting to receive tasks for execution. This method will not
616  * throw and is thread safe.
617  * @return The number of tasks either running or queued for
618  * execution.
619  *
620  * Since 2.0.12
621  */
622  unsigned int get_tasks() const;
623 
624  /**
625  * Gets the limit to the sum of the number of tasks which a
626  * TaskManager object may have running in the thread pool or queued
627  * for execution at any one time. On a 32-bit system, reaching this
628  * limit will normally cause the amount of memory which any process
629  * may allocate to be exceeded so the limit will in practice never be
630  * met (the add_task() or make_task_* methods will throw a
631  * std::bad_alloc exception before then). On a 64-bit system this
632  * limit will normally be the same as UINT_MAX (4,294,967,295 for a
633  * 32-bit unsigned int) which although likely to be unfeasibly large
634  * could in theory be reached with a system which can make around
635  * 70GB of memory available to the process for the TaskManager
636  * object. The add_task() and make_task_* methods will throw
637  * std::length_error if an attempt is made to exceed this limit and
638  * std::bad_alloc has not got there first.
639  *
640  * This method is thread safe.
641  *
642  * @return The maximum number of tasks which a TaskManager object may
643  * have either running or queued for execution at any one time.
644  * @exception std::bad_alloc This exception may be thrown the first
645  * time this method is called. Any subsequent calls will not throw
646  * if an earlier one did not (this method calculates the limit once
647  * only and then caches it using static local initialization).
648  *
649  * Since 2.0.31
650  */
651  static unsigned int get_max_tasks() {
652  // having max_tasks as a local static rather than a namespace
653  // static means that we cannot suffer from the static
654  // initialization order fiasco. Static local initialization is
655  // also guaranteed to be thread safe in C++11 on. Because this
656  // function just calls up a local static, we might as well make it
657  // inline.
658  static unsigned int max_tasks = init_max_tasks();
659  return max_tasks;
660  }
661 
662 /**
663  * Gets the length of time in milliseconds that threads greater in
664  * number than the minimum and not executing any tasks will remain in
665  * existence waiting for new tasks. This value is established
666  * initially by the 'idle' argument passed to the TaskManager
667  * constructor and can subequently be changed by calling
668  * set_idle_time(). The default value is 10000 (10 seconds). This
669  * method will not throw and is thread safe.
670  * @return The idle time in milliseconds.
671  *
672  * Since 2.0.12
673  */
674  unsigned int get_idle_time() const;
675 
676  /**
677  * Sets the length of time in milliseconds that threads greater in
678  * number than the minimum and not executing any tasks will remain in
679  * existence waiting for new tasks. This will only have effect for
680  * threads in the pool which begin waiting for new tasks after this
681  * method is called. This method will not throw and is thread safe.
682  * @param idle The length of the idle time in milliseconds during
683  * which threads will remain waiting for new tasks.
684  *
685  * Since 2.0.12
686  */
687  void set_idle_time(unsigned int idle);
688 
689  /**
690  * Gets the current blocking setting, which determines whether calls
691  * to stop_all() and the destructor will block waiting for all
692  * remaining tasks to complete. This value is established initially
693  * by the 'blocking' argument passed to the TaskManager constructor
694  * and can subequently be changed by calling set_blocking(). This
695  * method will not throw and is thread safe.
696  * @return The current blocking setting.
697  *
698  * Since 2.0.12
699  */
700  bool get_blocking() const;
701 
702  /**
703  * Sets the current blocking setting, which determines whether calls
704  * to stop_all() and the destructor will block waiting for all
705  * remaining tasks to complete. This method cannot be called after
706  * stop_all() has been called (if that is attempted,
707  * Cgu::Thread::TaskError will be thrown). It is thread safe.
708  * @param blocking The new blocking setting.
709  * @exception Cgu::Thread::TaskError This exception will be thrown if
710  * stop_all() has previously been called.
711  *
712  * Since 2.0.12
713  */
714  void set_blocking(bool blocking);
715 
716  /**
717  * Gets the current StopMode setting (either
718  * Cgu::Thread::TaskManager::wait_for_running or
719  * Cgu::Thread::TaskManager::wait_for_all) executed when running
720  * stop_all() or when the destructor is called. See the
721  * documentation on stop_all() for an explanation of the setting.
722  * This value is established initially by the 'mode' argument passed
723  * to the TaskManager constructor and can subequently be changed by
724  * calling set_stop_mode(). This method will not throw and is thread
725  * safe.
726  * @return The current StopMode setting.
727  *
728  * Since 2.0.12
729  */
730  StopMode get_stop_mode() const;
731 
732  /**
733  * Sets the current StopMode setting (either
734  * Cgu::Thread::TaskManager::wait_for_running or
735  * Cgu::Thread::TaskManager::wait_for_all) executed when running
736  * stop_all() or when the destructor is called. See the
737  * documentation on stop_all() for an explanation of the setting.
738  * This method will not throw and is thread safe.
739  * @param mode The new StopMode setting.
740  *
741  * Since 2.0.12
742  */
743  void set_stop_mode(StopMode mode);
744 
745  /**
746  * This will cause the TaskManager object to stop running tasks. The
747  * precise effect depends on the current StopMode and blocking
748  * settings. If StopMode is set to
749  * Cgu::Thread::TaskManager::wait_for_running, all queued tasks which
750  * are not yet running on a thread will be dispensed with, but any
751  * already running will be left to complete normally. If StopMode is
752  * set to Cgu::Thread::TaskManager::wait_for_all, both already
753  * running tasks and all tasks already queued will be permitted to
754  * execute and complete normally. If the blocking setting is set to
755  * true, this method will wait until all the tasks still to execute
756  * have finished before returning, and if false it will return
757  * straight away.
758  *
759  * The StopMode setting should not be set to
760  * Cgu::Thread::TaskManager::wait_for_running if, when this method is
761  * called, another thread may be waiting on the get() or move_get()
762  * method of a Cgu::AsyncResult object returned by
763  * Cgu::Thread::TaskManager::make_task_result(), as otherwise that
764  * wait may never end - choose the
765  * Cgu::Thread::TaskManager::wait_for_all setting instead in such
766  * cases.
767  *
768  * After this method has been called, any attempt to add further
769  * tasks with the add_task() method will fail, and add_task() will
770  * throw Cgu::Thread::TaskError.
771  *
772  * This method is thread safe (any thread may call it) unless the
773  * blocking setting is true, in which case no task running on the
774  * TaskManager object may call this method.
775  *
776  * @exception std::bad_alloc This exception will be thrown if memory
777  * is exhausted and the system throws in that case. (On systems with
778  * over-commit/lazy-commit combined with virtual memory (swap), it is
779  * rarely useful to check for memory exhaustion).
780  * @exception Cgu::Thread::TaskError This exception will be thrown if
781  * stop_all() has previously been called, unless that previous call
782  * threw std::bad_alloc: if std::bad_alloc is thrown, this method may
783  * be called again to stop all threads, once the memory deficiency is
784  * dealt with, but no other methods of the TaskManager object should
785  * be called.
786  *
787  * Since 2.0.12
788  */
789  void stop_all();
790 
791  /**
792  * This method adds a new task. If one or more threads in the pool
793  * are currently blocking and waiting for a task, then the task will
794  * begin executing immediately in one of the threads. If not, and
795  * the value returned by get_used_threads() is less than the value
796  * returned by get_max_threads(), a new thread will start and the
797  * task will execute immediately in the new thread. Otherwise, the
798  * task will be queued for execution as soon as a thread becomes
799  * available. Tasks will be executed in the order in which they are
800  * added to the ThreadManager object. This method is thread safe
801  * (any thread may call it, including any task running on the
802  * TaskManager object).
803  *
804  * A task may terminate itself prematurely by throwing
805  * Cgu::Thread::Exit. In addition, the implementation of TaskManager
806  * will consume any other exception escaping from the task callback
807  * and safely terminate the task concerned in order to protect the
808  * integrity of the TaskManager object. Where detecting any of these
809  * outcomes is important (usually it won't be), the two argument
810  * version of this method is available so that a 'fail' callback can
811  * be executed in these circumstances.
812  *
813  * @param task A callback representing the new task, as constructed
814  * by the Callback::lambda(), Callback::make() or
815  * Callback::make_ref() factory functions. Ownership is taken of
816  * this callback, and it will be disposed of when it has been
817  * finished with. If an exception propagates from the task, the
818  * exception will be consumed and (if the thrown object's type is not
819  * Cgu::Thread::Exit) a g_critical() warning will be issued. The
820  * destructors of any bound arguments in the callback must not throw.
821  * @exception std::bad_alloc This exception will be thrown if memory
822  * is exhausted and the system throws in that case. (On systems with
823  * over-commit/lazy-commit combined with virtual memory (swap), it is
824  * rarely useful to check for memory exhaustion). See also the
825  * documentation for the get_max_tasks() method about the possibility
826  * of std::length_error being thrown. If std::bad_alloc or
827  * std::length_error is thrown, the task will not start and the
828  * 'task' callback will be disposed of.
829  * @exception Cgu::Thread::TaskError This exception will be thrown if
830  * stop_all() has previously been called. It will also be thrown if
831  * is_error() would return true because this class's internal thread
832  * pool loop implementation has thrown std::bad_alloc, or a thread
833  * has failed to start correctly. (On systems with
834  * over-commit/lazy-commit combined with virtual memory (swap), it is
835  * rarely useful to check for memory exhaustion, but there may be
836  * some specialized cases where the return value of is_error() is
837  * useful.) If this exception is thrown, the task will not start and
838  * the 'task' callback will be disposed of.
839  *
840  * Since 2.0.12
841  */
842  void add_task(const Callback::Callback* task) {
843 #ifdef CGU_USE_AUTO_PTR
844  add_task(std::auto_ptr<const Callback::Callback>(task),
845  std::auto_ptr<const Callback::Callback>());
846 #else
847  add_task(std::unique_ptr<const Callback::Callback>(task),
848  std::unique_ptr<const Callback::Callback>());
849 #endif
850  }
851 
852  /**
853  * This method adds a new task. If one or more threads in the pool
854  * are currently blocking and waiting for a task, then the task will
855  * begin executing immediately in one of the threads. If not, and
856  * the value returned by get_used_threads() is less than the value
857  * returned by get_max_threads(), a new thread will start and the
858  * task will execute immediately in the new thread. Otherwise, the
859  * task will be queued for execution as soon as a thread becomes
860  * available. Tasks will be executed in the order in which they are
861  * added to the ThreadManager object. This method is thread safe
862  * (any thread may call it, including any task running on the
863  * TaskManager object).
864  *
865  * A task may terminate itself prematurely by throwing
866  * Cgu::Thread::Exit. In addition, the implementation of TaskManager
867  * will consume any other exception escaping from the task callback
868  * and safely terminate the task concerned in order to protect the
869  * integrity of the TaskManager object. Where detecting any of these
870  * outcomes is important (usually it won't be), a callback can be
871  * passed to the 'fail' argument which will execute if, and only if,
872  * either Cgu::Thread::Exit is thrown or some other exception has
873  * propagated from the task. This 'fail' callback is different from
874  * the 'fail' callback of Cgu::Thread::Future objects (programming
875  * for many tasks to a lesser number of threads requires different
876  * approaches from programming for one thread per task), and it
877  * executes in the task thread rather than executing in a glib main
878  * loop (however, the 'fail' callback can of course call
879  * Cgu::Callback::post() to execute another callback in a main loop,
880  * if that is what is wanted).
881  *
882  * @param task A callback representing the new task, as constructed
883  * by the Callback::lambda(), Callback::make() or
884  * Callback::make_ref() factory functions. If an exception
885  * propagates from the task, the exception will be consumed and the
886  * 'fail' callback will execute.
887  * @param fail A callback (as constructed by the Callback::lambda(),
888  * Callback::make() or Callback::make_ref() factory functions) which
889  * will be executed if the function or callable object executed by
890  * the 'task' callback exits by throwing Thread::Exit or some other
891  * exception. If an exception propagates from the 'fail' callback,
892  * this will be consumed to protect the TaskManager object, and a
893  * g_critical() warning will be issued.
894  * @exception std::bad_alloc This exception will be thrown if memory
895  * is exhausted and the system throws in that case. (On systems with
896  * over-commit/lazy-commit combined with virtual memory (swap), it is
897  * rarely useful to check for memory exhaustion). See also the
898  * documentation for the get_max_tasks() method about the possibility
899  * of std::length_error being thrown. If std::bad_alloc or
900  * std::length_error is thrown, the task will not start (which also
901  * means that the 'fail' callback will not execute).
902  * @exception Cgu::Thread::TaskError This exception will be thrown if
903  * stop_all() has previously been called. It will also be thrown if
904  * is_error() would return true because this class's internal thread
905  * pool loop implementation has thrown std::bad_alloc, or a thread
906  * has failed to start correctly. (On systems with
907  * over-commit/lazy-commit combined with virtual memory (swap), it is
908  * rarely useful to check for memory exhaustion, but there may be
909  * some specialized cases where the return value of is_error() is
910  * useful.) If this exception is thrown, the task will not start
911  * (which also means that the 'fail' callback will not execute).
912  * @note 1. Question: why does the single argument version of
913  * add_task() take a pointer, and this version take the callbacks by
914  * std::unique_ptr? Answer: The two argument version of add_task()
915  * takes its arguments by std::unique_ptr in order to be exception
916  * safe if the first callback to be constructed is constructed
917  * correctly but construction of the second callback object throws.
918  * @note 2. If the library is compiled using the \--with-auto-ptr
919  * configuration option, then this method's signature is
920  * add_task(std::auto_ptr<const Callback::Callback>,
921  * std::auto_ptr<const Callback::Callback>) in order to retain
922  * compatibility with the 1.2 series of the library.
923  *
924  * Since 2.0.12
925  */
926 #ifdef CGU_USE_AUTO_PTR
927  void add_task(std::auto_ptr<const Callback::Callback> task,
928  std::auto_ptr<const Callback::Callback> fail);
929 #else
930  void add_task(std::unique_ptr<const Callback::Callback> task,
931  std::unique_ptr<const Callback::Callback> fail);
932 #endif
933 
934  /**
935  * This will return true if a thread required by the thread pool has
936  * failed to start correctly because of memory exhaustion or because
937  * pthread has run out of other resources to start new threads, or
938  * because an internal operation has thrown std::bad_alloc. (On
939  * systems with over-commit/lazy-commit combined with virtual memory
940  * (swap), it is rarely useful to check for memory exhaustion, and
941  * even more so where glib is used, as that terminates a program if
942  * memory cannot be obtained from the operating system, but there may
943  * be some specialized cases where the return value of this method is
944  * useful - this class does not use any glib functions which might
945  * cause such termination.) This method will not throw and is thread
946  * safe.
947  *
948  * Since 2.0.12
949  */
950  bool is_error() const;
951 
952  /**
953  * This is a wrapper which takes a member function pointer to a
954  * member function which returns a value, together with arguments,
955  * and constructs a TaskManager task which will execute that function
956  * by calling add_task() with an appropriate callback object, and
957  * returns a Cgu::AsyncResult object (held by Cgu::SharedLockPtr)
958  * which will provide the value that the function returns. Apart
959  * from the absence of a 'one thread per task' model, this method
960  * therefore provides a similar interface to the one provided by
961  * Cgu::Thread::Future. It is thread safe: any thread may call this
962  * method, including another task running on the TaskManager object,
963  * but see the introductory remarks about the use of the
964  * TaskManager::IncHandle scoped handle class where a task running on
965  * a TaskManager object is to block on one of its sub-tasks. See
966  * also the documentation on add_task() for further information about
967  * how task execution works.
968  *
969  * This method can take up to three bound arguments for the target
970  * member function.
971  *
972  * If the function passed to this method exits by throwing
973  * Thread::Exit or some other exception, then the exception will be
974  * consumed and the returned Cgu::AsyncResult object's get() or
975  * move_get() method will unblock and its get_error() method will
976  * return -1.
977  *
978  * @param t The object whose member function passed to this method is
979  * to execute as a task.
980  * @param func The member function to be executed as a task.
981  * @param args The arguments to be passed to that member function.
982  * @exception std::bad_alloc This exception will be thrown if memory
983  * is exhausted and the system throws in that case. (On systems with
984  * over-commit/lazy-commit combined with virtual memory (swap), it is
985  * rarely useful to check for memory exhaustion). See also the
986  * documentation for the get_max_tasks() method about the possibility
987  * of std::length_error being thrown. If std::bad_alloc or
988  * std::length_error is thrown, the task will not start.
989  * @exception Cgu::Thread::TaskError This exception will be thrown if
990  * stop_all() has previously been called. It will also be thrown if
991  * is_error() would return true because this class's internal thread
992  * pool loop implementation has thrown std::bad_alloc, or a thread
993  * has failed to start correctly. (On systems with
994  * over-commit/lazy-commit combined with virtual memory (swap), it is
995  * rarely useful to check for memory exhaustion, but there may be
996  * some specialized cases where the return value of is_error() is
997  * useful.) If this exception is thrown, the task will not start.
998  * @note This method will also throw if the copy or move constructor
999  * of a bound argument throws. If such an exception is thrown, the
1000  * task will not start.
1001  *
1002  * Since 2.0.13
1003  */
1004 
1005  template <class Ret, class... Params, class... Args, class T>
1007  Ret (T::*func)(Params...),
1008  Args&&... args);
1009 
1010  /**
1011  * This is a wrapper which takes a member function pointer to a
1012  * member function which returns a value, together with arguments,
1013  * and constructs a TaskManager task which will execute that function
1014  * by calling add_task() with an appropriate callback object, and
1015  * causes the 'when' callback passed as an argument to this method to
1016  * be executed by a glib main loop if and when the task finishes
1017  * correctly - the 'when' callback is passed the member function's
1018  * return value when it is invoked. It is thread safe (any thread
1019  * may call this method, including another task running on the
1020  * TaskManager object). Apart from the absence of a 'one thread per
1021  * task' model, this method therefore provides a similar interface to
1022  * the one provided by Cgu::Thread::Future. See the documentation on
1023  * add_task() for further information about how task execution works.
1024  *
1025  * This method can take up to three bound arguments for the target
1026  * member function.
1027  *
1028  * Note that unlike add_task(), but like the 'fail' callback of
1029  * Cgu::Thread::Future objects, if a fail callback is provided to
1030  * this method and it executes, it will execute in the glib main loop
1031  * whose GMainContext object is passed to the 'context' argument of
1032  * this method.
1033  *
1034  * Note also that if releasers are provided for the 'when' or 'fail'
1035  * callbacks, these are passed by pointer and not by reference (this
1036  * is so that a NULL pointer can indicate that no releaser is to be
1037  * provided). If provided, a releaser will enable automatic
1038  * disconnection of the 'when' or 'fail' callback, if the object
1039  * having the callback function as a member is destroyed. For this to
1040  * be race free, the lifetime of that object must be controlled by
1041  * the thread in whose main loop the 'when' or 'fail' callback will
1042  * execute.
1043  *
1044  * The make_task_when() method is similar to this method but provides
1045  * an abbreviated set of paramaters suitable for most cases. This
1046  * method is for use where releasers or a 'fail' callback are
1047  * required.
1048  *
1049  * @param when A callback which will be executed if and when the
1050  * function passed to this method finishes correctly. The callback is
1051  * passed that function's return value when it is invoked. If an
1052  * exception propagates from the 'when' callback, this will be
1053  * consumed and a g_critical() warning will be issued. The callback
1054  * will execute in the glib main loop whose GMainContext object is
1055  * passed to the 'context' argument of this method.
1056  * @param when_releaser A pointer to a Releaser object for automatic
1057  * disconnection of the 'when' callback before it executes in a main
1058  * loop (mainly relevant if the callback represents a non-static
1059  * member function of an object which may be destroyed before the
1060  * callback executes). A value of 0/NULL/nullptr indicates no
1061  * releaser.
1062  * @param fail A callback which will be executed if the 'when'
1063  * callback does not execute. This would happen if the function
1064  * passed to this method exits by throwing Thread::Exit or some other
1065  * exception, if the copy constructor of a non-reference argument of
1066  * that function throws, if the move constructor (or if it has none,
1067  * the copy constructor) of that function's return value throws or if
1068  * the 'when' callback does not execute because the internal
1069  * implementation of this wrapper throws std::bad_alloc (which will
1070  * not happen if the library has been installed using the
1071  * \--with-glib-memory-slices-no-compat configuration option: instead
1072  * glib will terminate the program if it is unable to obtain memory
1073  * from the operating system). If an exception propagates from the
1074  * 'fail' callback, this will be consumed and a g_critical() warning
1075  * will be issued. The callback will execute in the glib main loop
1076  * whose GMainContext object is passed to the 'context' argument of
1077  * this method. An empty std::unique_ptr object indicates no 'fail'
1078  * callback.
1079  * @param fail_releaser A pointer to a Releaser object for automatic
1080  * disconnection of the 'fail' callback before it executes in a main
1081  * loop (mainly relevant if the callback represents a non-static
1082  * member function of an object which may be destroyed before the
1083  * callback executes). A value of 0/NULL/nullptr indicates no
1084  * releaser.
1085  * @param priority The priority to be given in the main loop to the
1086  * 'when' callback or any 'fail' callback. In ascending order of
1087  * priorities, priorities are G_PRIORITY_LOW,
1088  * G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT
1089  * and G_PRIORITY_HIGH. This determines the order in which the
1090  * callback will appear in the event list in the main loop, not the
1091  * priority which the OS will adopt.
1092  * @param context The glib main context of the main loop in which the
1093  * 'when' callback or any 'fail' callback is to be executed. A value
1094  * 0/NULL/nullptr will cause the callback to be executed in the main
1095  * program loop.
1096  * @param t The object whose member function passed to this method is
1097  * to execute as a task.
1098  * @param func The member function to be executed as a task. If an
1099  * exception propagates from the task, the exception will be consumed
1100  * and the 'fail' callback will execute.
1101  * @param args The arguments to be passed to that member function.
1102  * @exception std::bad_alloc This exception will be thrown if memory
1103  * is exhausted and the system throws in that case. (On systems with
1104  * over-commit/lazy-commit combined with virtual memory (swap), it is
1105  * rarely useful to check for memory exhaustion). See also the
1106  * documentation for the get_max_tasks() method about the possibility
1107  * of std::length_error being thrown. If std::bad_alloc or
1108  * std::length_error is thrown, the task will not start (which also
1109  * means that the 'when' and 'fail' callbacks will not execute).
1110  * @exception Cgu::Thread::TaskError This exception will be thrown if
1111  * stop_all() has previously been called. It will also be thrown if
1112  * is_error() would return true because this class's internal thread
1113  * pool loop implementation has thrown std::bad_alloc, or a thread
1114  * has failed to start correctly. (On systems with
1115  * over-commit/lazy-commit combined with virtual memory (swap), it is
1116  * rarely useful to check for memory exhaustion, but there may be
1117  * some specialized cases where the return value of is_error() is
1118  * useful.) If this exception is thrown, the task will not start
1119  * (which also means that the 'when' and 'fail' callbacks will not
1120  * execute).
1121  * @note 1. This method will also throw if the copy or move
1122  * constructor of a bound argument throws. If such an exception is
1123  * thrown, the task will not start (which also means that the 'when'
1124  * and 'fail' callbacks will not execute).
1125  * @note 2. If a 'when_releaser' or a 'fail_releaser' object is
1126  * provided, it is in theory possible (if memory is exhausted and the
1127  * system throws in that case) that an internal SafeEmitterArg object
1128  * will throw std::bad_alloc when emitting/executing the 'when' or
1129  * 'fail' callback in the glib main loop, with the result that the
1130  * relevant callback will not execute (instead the exception will be
1131  * consumed and a g_critical() warning will be issued). This is
1132  * rarely of any relevance because glib will abort the program if it
1133  * is itself unable to obtain memory from the operating system.
1134  * However, where it is relevant, design the program so that it is
1135  * not necessary to provide a releaser object.
1136  * @note 3. If the library is compiled using the \--with-auto-ptr
1137  * configuration option, then this method uses std::auto_ptr in place
1138  * of std::unique_ptr in its signature in order to retain
1139  * compatibility with the 1.2 series of the library.
1140  *
1141  * Since 2.0.13
1142  */
1143  template <class Ret, class... Params, class... Args, class T>
1144 #ifdef CGU_USE_AUTO_PTR
1145  void make_task_when_full(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1146  Cgu::Releaser* when_releaser,
1147  std::auto_ptr<const Cgu::Callback::Callback> fail,
1148  Cgu::Releaser* fail_releaser,
1149  gint priority,
1150  GMainContext* context,
1151  T& t,
1152  Ret (T::*func)(Params...),
1153  Args&&... args);
1154 #else
1155  void make_task_when_full(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1156  Cgu::Releaser* when_releaser,
1157  std::unique_ptr<const Cgu::Callback::Callback> fail,
1158  Cgu::Releaser* fail_releaser,
1159  gint priority,
1160  GMainContext* context,
1161  T& t,
1162  Ret (T::*func)(Params...),
1163  Args&&... args);
1164 #endif
1165 
1166  /**
1167  * This is an abbreviated version of make_task_when_full(), which is
1168  * for use when it is known that invocation of the member function
1169  * passed to this method, the copy constructors of any non-reference
1170  * arguments of that function and the move constructor (or if it has
1171  * none, the copy constructor) of that function's return value do not
1172  * throw anything other than std::bad_alloc, and the user is not
1173  * interested in std::bad_alloc and does not need a Cgu::Releaser
1174  * object for the 'when' callback (which is likely to cover the
1175  * majority of uses, particularly when composing tasks using glib
1176  * because glib terminates the program if it is unable to obtain
1177  * memory).
1178  *
1179  * This method can take up to three bound arguments for the target
1180  * member function.
1181  *
1182  * Like make_task_when_full(), this method is a wrapper which takes a
1183  * member function pointer to a member function which returns a
1184  * value, together with arguments, and constructs a TaskManager task
1185  * which will execute that function by calling add_task() with an
1186  * appropriate callback object, and causes the 'when' callback passed
1187  * as an argument to this method to be executed by a glib main loop
1188  * if and when the task finishes correctly - the 'when' callback is
1189  * passed the member function's return value when it is invoked. It
1190  * is thread safe (any thread may call this method, including another
1191  * task running on the TaskManager object). Apart from the absence
1192  * of a 'one thread per task' model, this method therefore provides a
1193  * similar interface to the one provided by Cgu::Thread::Future. See
1194  * the documentation on add_task() for further information about how
1195  * task execution works.
1196  *
1197  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
1198  * in the main loop.
1199  *
1200  * @param when A callback which will be executed if and when the
1201  * function passed to this method finishes correctly. The callback is
1202  * passed that function's return value when it is invoked. If an
1203  * exception propagates from the 'when' callback, this will be
1204  * consumed and a g_critical() warning will be issued. The callback
1205  * will execute in the glib main loop whose GMainContext object is
1206  * passed to the 'context' argument of this method.
1207  * @param context The glib main context of the main loop in which the
1208  * 'when' callback is to be executed. A value 0/NULL/nullptr will
1209  * cause the callback to be executed in the main program loop.
1210  * @param t The object whose member function passed to this method is
1211  * to execute as a task.
1212  * @param func The member function to be executed as a task. If an
1213  * exception propagates from the task, the exception will be consumed
1214  * and (if the thrown object's type is not Cgu::Thread::Exit) a
1215  * g_critical() warning will be issued.
1216  * @param args The arguments to be passed to that member function.
1217  * @exception std::bad_alloc This exception will be thrown if memory
1218  * is exhausted and the system throws in that case. (On systems with
1219  * over-commit/lazy-commit combined with virtual memory (swap), it is
1220  * rarely useful to check for memory exhaustion). See also the
1221  * documentation for the get_max_tasks() method about the possibility
1222  * of std::length_error being thrown. If std::bad_alloc or
1223  * std::length_error is thrown, the task will not start (which also
1224  * means that the 'when' callback will not execute).
1225  * @exception Cgu::Thread::TaskError This exception will be thrown if
1226  * stop_all() has previously been called. It will also be thrown if
1227  * is_error() would return true because this class's internal thread
1228  * pool loop implementation has thrown std::bad_alloc, or a thread
1229  * has failed to start correctly. (On systems with
1230  * over-commit/lazy-commit combined with virtual memory (swap), it is
1231  * rarely useful to check for memory exhaustion, but there may be
1232  * some specialized cases where the return value of is_error() is
1233  * useful.) If this exception is thrown, the task will not start
1234  * (which also means that the 'when' callback will not execute).
1235  * @note 1. This method will also throw if the copy or move
1236  * constructor of a bound argument throws. If such an exception is
1237  * thrown, the task will not start (which also means that the 'when'
1238  * callback will not execute).
1239  * @note 2. If the library is compiled using the \--with-auto-ptr
1240  * configuration option, then this method uses std::auto_ptr in place
1241  * of std::unique_ptr in its signature in order to retain
1242  * compatibility with the 1.2 series of the library.
1243  * @note 3. As mentioned in describing 'func' above, if 'func' exits
1244  * by throwing an exception the exception will be consumed and (if
1245  * the thrown object's type is not Cgu::Thread::Exit) a g_critical()
1246  * warning will be issued. The same will occur if the copy
1247  * constructor of a non-reference argument of 'func' throws when
1248  * invoking 'func' or the move constructor (or if it has none, the
1249  * copy constructor) of the return value of 'func' throws, or if the
1250  * internal implementation of this wrapper throws std::bad_alloc on
1251  * executing 'func'.
1252  *
1253  * Since 2.0.13
1254  */
1255  template <class Ret, class... Params, class... Args, class T>
1256 #ifdef CGU_USE_AUTO_PTR
1257  void make_task_when(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1258  GMainContext* context,
1259  T& t,
1260  Ret (T::*func)(Params...),
1261  Args&&... args) {
1262  static_assert(sizeof...(Args) < 4,
1263  "No greater than three bound arguments can be passed to "
1264  "TaskManager::make_task_when() taking a member function.");
1265 
1266  make_task_when_full(when,
1267  0,
1268  std::auto_ptr<const Cgu::Callback::Callback>(),
1269  0,
1270  G_PRIORITY_DEFAULT,
1271  context,
1272  t,
1273  func,
1274  std::forward<Args>(args)...);
1275  }
1276 #else
1277  void make_task_when(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1278  GMainContext* context,
1279  T& t,
1280  Ret (T::*func)(Params...),
1281  Args&&... args) {
1282  static_assert(sizeof...(Args) < 4,
1283  "No greater than three bound arguments can be passed to "
1284  "TaskManager::make_task_when() taking a member function.");
1285 
1286  make_task_when_full(std::move(when),
1287  0,
1288  std::unique_ptr<const Cgu::Callback::Callback>(),
1289  0,
1290  G_PRIORITY_DEFAULT,
1291  context,
1292  t,
1293  func,
1294  std::forward<Args>(args)...);
1295  }
1296 #endif
1297 
1298  /**
1299  * This is a wrapper which takes a member function pointer to a
1300  * member function which returns a value, together with arguments,
1301  * and constructs a TaskManager task which will execute that function
1302  * by calling add_task() with an appropriate callback object, and
1303  * returns a Cgu::AsyncResult object (held by Cgu::SharedLockPtr)
1304  * which will provide the value that the function returns. Apart
1305  * from the absence of a 'one thread per task' model, this method
1306  * therefore provides a similar interface to the one provided by
1307  * Cgu::Thread::Future. It is thread safe: any thread may call this
1308  * method, including another task running on the TaskManager object,
1309  * but see the introductory remarks about the use of the
1310  * TaskManager::IncHandle scoped handle class where a task running on
1311  * a TaskManager object is to block on one of its sub-tasks. See
1312  * also the documentation on add_task() for further information about
1313  * how task execution works.
1314  *
1315  * This method can take up to three bound arguments for the target
1316  * member function.
1317  *
1318  * If the function passed to this method exits by throwing
1319  * Thread::Exit or some other exception, then the exception will be
1320  * consumed and the returned Cgu::AsyncResult object's get() or
1321  * move_get() method will unblock and its get_error() method will
1322  * return -1.
1323  *
1324  * @param t The object whose member function passed to this method is
1325  * to execute as a task.
1326  * @param func The member function to be executed as a task.
1327  * @param args The arguments to be passed to that member function.
1328  * @exception std::bad_alloc This exception will be thrown if memory
1329  * is exhausted and the system throws in that case. (On systems with
1330  * over-commit/lazy-commit combined with virtual memory (swap), it is
1331  * rarely useful to check for memory exhaustion). See also the
1332  * documentation for the get_max_tasks() method about the possibility
1333  * of std::length_error being thrown. If std::bad_alloc or
1334  * std::length_error is thrown, the task will not start.
1335  * @exception Cgu::Thread::TaskError This exception will be thrown if
1336  * stop_all() has previously been called. It will also be thrown if
1337  * is_error() would return true because this class's internal thread
1338  * pool loop implementation has thrown std::bad_alloc, or a thread
1339  * has failed to start correctly. (On systems with
1340  * over-commit/lazy-commit combined with virtual memory (swap), it is
1341  * rarely useful to check for memory exhaustion, but there may be
1342  * some specialized cases where the return value of is_error() is
1343  * useful.) If this exception is thrown, the task will not start.
1344  * @note This method will also throw if the copy or move constructor
1345  * of a bound argument throws. If such an exception is thrown, the
1346  * task will not start.
1347  *
1348  * Since 2.0.13
1349  */
1350 
1351  template <class Ret, class... Params, class... Args, class T>
1353  Ret (T::*func)(Params...) const,
1354  Args&&... args);
1355 
1356  /**
1357  * This is a wrapper which takes a member function pointer to a
1358  * member function which returns a value, together with arguments,
1359  * and constructs a TaskManager task which will execute that function
1360  * by calling add_task() with an appropriate callback object, and
1361  * causes the 'when' callback passed as an argument to this method to
1362  * be executed by a glib main loop if and when the task finishes
1363  * correctly - the 'when' callback is passed the member function's
1364  * return value when it is invoked. It is thread safe (any thread
1365  * may call this method, including another task running on the
1366  * TaskManager object). Apart from the absence of a 'one thread per
1367  * task' model, this method therefore provides a similar interface to
1368  * the one provided by Cgu::Thread::Future. See the documentation on
1369  * add_task() for further information about how task execution works.
1370  *
1371  * This method can take up to three bound arguments for the target
1372  * member function.
1373  *
1374  * Note that unlike add_task(), but like the 'fail' callback of
1375  * Cgu::Thread::Future objects, if a fail callback is provided to
1376  * this method and it executes, it will execute in the glib main loop
1377  * whose GMainContext object is passed to the 'context' argument of
1378  * this method.
1379  *
1380  * Note also that if releasers are provided for the 'when' or 'fail'
1381  * callbacks, these are passed by pointer and not by reference (this
1382  * is so that a NULL pointer can indicate that no releaser is to be
1383  * provided). If provided, a releaser will enable automatic
1384  * disconnection of the 'when' or 'fail' callback, if the object
1385  * having the callback function as a member is destroyed. For this to
1386  * be race free, the lifetime of that object must be controlled by
1387  * the thread in whose main loop the 'when' or 'fail' callback will
1388  * execute.
1389  *
1390  * The make_task_when() method is similar to this method but provides
1391  * an abbreviated set of paramaters suitable for most cases. This
1392  * method is for use where releasers or a 'fail' callback are
1393  * required.
1394  *
1395  * @param when A callback which will be executed if and when the
1396  * function passed to this method finishes correctly. The callback is
1397  * passed that function's return value when it is invoked. If an
1398  * exception propagates from the 'when' callback, this will be
1399  * consumed and a g_critical() warning will be issued. The callback
1400  * will execute in the glib main loop whose GMainContext object is
1401  * passed to the 'context' argument of this method.
1402  * @param when_releaser A pointer to a Releaser object for automatic
1403  * disconnection of the 'when' callback before it executes in a main
1404  * loop (mainly relevant if the callback represents a non-static
1405  * member function of an object which may be destroyed before the
1406  * callback executes). A value of 0/NULL/nullptr indicates no
1407  * releaser.
1408  * @param fail A callback which will be executed if the 'when'
1409  * callback does not execute. This would happen if the function
1410  * passed to this method exits by throwing Thread::Exit or some other
1411  * exception, if the copy constructor of a non-reference argument of
1412  * that function throws, if the move constructor (or if it has none,
1413  * the copy constructor) of that function's return value throws or if
1414  * the 'when' callback does not execute because the internal
1415  * implementation of this wrapper throws std::bad_alloc (which will
1416  * not happen if the library has been installed using the
1417  * \--with-glib-memory-slices-no-compat configuration option: instead
1418  * glib will terminate the program if it is unable to obtain memory
1419  * from the operating system). If an exception propagates from the
1420  * 'fail' callback, this will be consumed and a g_critical() warning
1421  * will be issued. The callback will execute in the glib main loop
1422  * whose GMainContext object is passed to the 'context' argument of
1423  * this method. An empty std::unique_ptr object indicates no 'fail'
1424  * callback.
1425  * @param fail_releaser A pointer to a Releaser object for automatic
1426  * disconnection of the 'fail' callback before it executes in a main
1427  * loop (mainly relevant if the callback represents a non-static
1428  * member function of an object which may be destroyed before the
1429  * callback executes). A value of 0/NULL/nullptr indicates no
1430  * releaser.
1431  * @param priority The priority to be given in the main loop to the
1432  * 'when' callback or any 'fail' callback. In ascending order of
1433  * priorities, priorities are G_PRIORITY_LOW,
1434  * G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT
1435  * and G_PRIORITY_HIGH. This determines the order in which the
1436  * callback will appear in the event list in the main loop, not the
1437  * priority which the OS will adopt.
1438  * @param context The glib main context of the main loop in which the
1439  * 'when' callback or any 'fail' callback is to be executed. A value
1440  * 0/NULL/nullptr will cause the callback to be executed in the main
1441  * program loop.
1442  * @param t The object whose member function passed to this method is
1443  * to execute as a task.
1444  * @param func The member function to be executed as a task. If an
1445  * exception propagates from the task, the exception will be consumed
1446  * and the 'fail' callback will execute.
1447  * @param args The arguments to be passed to that member function.
1448  * @exception std::bad_alloc This exception will be thrown if memory
1449  * is exhausted and the system throws in that case. (On systems with
1450  * over-commit/lazy-commit combined with virtual memory (swap), it is
1451  * rarely useful to check for memory exhaustion). See also the
1452  * documentation for the get_max_tasks() method about the possibility
1453  * of std::length_error being thrown. If std::bad_alloc or
1454  * std::length_error is thrown, the task will not start (which also
1455  * means that the 'when' and 'fail' callbacks will not execute).
1456  * @exception Cgu::Thread::TaskError This exception will be thrown if
1457  * stop_all() has previously been called. It will also be thrown if
1458  * is_error() would return true because this class's internal thread
1459  * pool loop implementation has thrown std::bad_alloc, or a thread
1460  * has failed to start correctly. (On systems with
1461  * over-commit/lazy-commit combined with virtual memory (swap), it is
1462  * rarely useful to check for memory exhaustion, but there may be
1463  * some specialized cases where the return value of is_error() is
1464  * useful.) If this exception is thrown, the task will not start
1465  * (which also means that the 'when' and 'fail' callbacks will not
1466  * execute).
1467  * @note 1. This method will also throw if the copy or move
1468  * constructor of a bound argument throws. If such an exception is
1469  * thrown, the task will not start (which also means that the 'when'
1470  * and 'fail' callbacks will not execute).
1471  * @note 2. If a 'when_releaser' or a 'fail_releaser' object is
1472  * provided, it is in theory possible (if memory is exhausted and the
1473  * system throws in that case) that an internal SafeEmitterArg object
1474  * will throw std::bad_alloc when emitting/executing the 'when' or
1475  * 'fail' callback in the glib main loop, with the result that the
1476  * relevant callback will not execute (instead the exception will be
1477  * consumed and a g_critical() warning will be issued). This is
1478  * rarely of any relevance because glib will abort the program if it
1479  * is itself unable to obtain memory from the operating system.
1480  * However, where it is relevant, design the program so that it is
1481  * not necessary to provide a releaser object.
1482  * @note 3. If the library is compiled using the \--with-auto-ptr
1483  * configuration option, then this method uses std::auto_ptr in place
1484  * of std::unique_ptr in its signature in order to retain
1485  * compatibility with the 1.2 series of the library.
1486  *
1487  * Since 2.0.13
1488  */
1489  template <class Ret, class... Params, class... Args, class T>
1490 #ifdef CGU_USE_AUTO_PTR
1491  void make_task_when_full(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1492  Cgu::Releaser* when_releaser,
1493  std::auto_ptr<const Cgu::Callback::Callback> fail,
1494  Cgu::Releaser* fail_releaser,
1495  gint priority,
1496  GMainContext* context,
1497  const T& t,
1498  Ret (T::*func)(Params...) const,
1499  Args&&... args);
1500 #else
1501  void make_task_when_full(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1502  Cgu::Releaser* when_releaser,
1503  std::unique_ptr<const Cgu::Callback::Callback> fail,
1504  Cgu::Releaser* fail_releaser,
1505  gint priority,
1506  GMainContext* context,
1507  const T& t,
1508  Ret (T::*func)(Params...) const,
1509  Args&&... args);
1510 #endif
1511 
1512  /**
1513  * This is an abbreviated version of make_task_when_full(), which is
1514  * for use when it is known that invocation of the member function
1515  * passed to this method, the copy constructors of any non-reference
1516  * arguments of that function and the move constructor (or if it has
1517  * none, the copy constructor) of that function's return value do not
1518  * throw anything other than std::bad_alloc, and the user is not
1519  * interested in std::bad_alloc and does not need a Cgu::Releaser
1520  * object for the 'when' callback (which is likely to cover the
1521  * majority of uses, particularly when composing tasks using glib
1522  * because glib terminates the program if it is unable to obtain
1523  * memory).
1524  *
1525  * This method can take up to three bound arguments for the target
1526  * member function.
1527  *
1528  * Like make_task_when_full(), this method is a wrapper which takes a
1529  * member function pointer to a member function which returns a
1530  * value, together with arguments, and constructs a TaskManager task
1531  * which will execute that function by calling add_task() with an
1532  * appropriate callback object, and causes the 'when' callback passed
1533  * as an argument to this method to be executed by a glib main loop
1534  * if and when the task finishes correctly - the 'when' callback is
1535  * passed the member function's return value when it is invoked. It
1536  * is thread safe (any thread may call this method, including another
1537  * task running on the TaskManager object). Apart from the absence
1538  * of a 'one thread per task' model, this method therefore provides a
1539  * similar interface to the one provided by Cgu::Thread::Future. See
1540  * the documentation on add_task() for further information about how
1541  * task execution works.
1542  *
1543  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
1544  * in the main loop.
1545  *
1546  * @param when A callback which will be executed if and when the
1547  * function passed to this method finishes correctly. The callback is
1548  * passed that function's return value when it is invoked. If an
1549  * exception propagates from the 'when' callback, this will be
1550  * consumed and a g_critical() warning will be issued. The callback
1551  * will execute in the glib main loop whose GMainContext object is
1552  * passed to the 'context' argument of this method.
1553  * @param context The glib main context of the main loop in which the
1554  * 'when' callback is to be executed. A value 0/NULL/nullptr will
1555  * cause the callback to be executed in the main program loop.
1556  * @param t The object whose member function passed to this method is
1557  * to execute as a task.
1558  * @param func The member function to be executed as a task. If an
1559  * exception propagates from the task, the exception will be consumed
1560  * and (if the thrown object's type is not Cgu::Thread::Exit) a
1561  * g_critical() warning will be issued.
1562  * @param args The arguments to be passed to that member function.
1563  * @exception std::bad_alloc This exception will be thrown if memory
1564  * is exhausted and the system throws in that case. (On systems with
1565  * over-commit/lazy-commit combined with virtual memory (swap), it is
1566  * rarely useful to check for memory exhaustion). See also the
1567  * documentation for the get_max_tasks() method about the possibility
1568  * of std::length_error being thrown. If std::bad_alloc or
1569  * std::length_error is thrown, the task will not start (which also
1570  * means that the 'when' callback will not execute).
1571  * @exception Cgu::Thread::TaskError This exception will be thrown if
1572  * stop_all() has previously been called. It will also be thrown if
1573  * is_error() would return true because this class's internal thread
1574  * pool loop implementation has thrown std::bad_alloc, or a thread
1575  * has failed to start correctly. (On systems with
1576  * over-commit/lazy-commit combined with virtual memory (swap), it is
1577  * rarely useful to check for memory exhaustion, but there may be
1578  * some specialized cases where the return value of is_error() is
1579  * useful.) If this exception is thrown, the task will not start
1580  * (which also means that the 'when' callback will not execute).
1581  * @note 1. This method will also throw if the copy or move constructor
1582  * of a bound argument throws. If such an exception is thrown, the
1583  * task will not start (which also means that the 'when' callback
1584  * will not execute).
1585  * @note 2. If the library is compiled using the \--with-auto-ptr
1586  * configuration option, then this method uses std::auto_ptr in place
1587  * of std::unique_ptr in its signature in order to retain
1588  * compatibility with the 1.2 series of the library.
1589  * @note 3. As mentioned in describing 'func' above, if 'func' exits
1590  * by throwing an exception the exception will be consumed and (if
1591  * the thrown object's type is not Cgu::Thread::Exit) a g_critical()
1592  * warning will be issued. The same will occur if the copy
1593  * constructor of a non-reference argument of 'func' throws when
1594  * invoking 'func' or the move constructor (or if it has none, the
1595  * copy constructor) of the return value of 'func' throws, or if the
1596  * internal implementation of this wrapper throws std::bad_alloc on
1597  * executing 'func'.
1598  *
1599  * Since 2.0.13
1600  */
1601  template <class Ret, class... Params, class... Args, class T>
1602 #ifdef CGU_USE_AUTO_PTR
1603  void make_task_when(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1604  GMainContext* context,
1605  const T& t,
1606  Ret (T::*func)(Params...) const,
1607  Args&&... args) {
1608  static_assert(sizeof...(Args) < 4,
1609  "No greater than three bound arguments can be passed to "
1610  "TaskManager::make_task_when() taking a member function.");
1611 
1612  make_task_when_full(when,
1613  0,
1614  std::auto_ptr<const Cgu::Callback::Callback>(),
1615  0,
1616  G_PRIORITY_DEFAULT,
1617  context,
1618  t,
1619  func,
1620  std::forward<Args>(args)...);
1621  }
1622 #else
1623  void make_task_when(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1624  GMainContext* context,
1625  const T& t,
1626  Ret (T::*func)(Params...) const,
1627  Args&&... args) {
1628  static_assert(sizeof...(Args) < 4,
1629  "No greater than three bound arguments can be passed to "
1630  "TaskManager::make_task_when() taking a member function.");
1631 
1632  make_task_when_full(std::move(when),
1633  0,
1634  std::unique_ptr<const Cgu::Callback::Callback>(),
1635  0,
1636  G_PRIORITY_DEFAULT,
1637  context,
1638  t,
1639  func,
1640  std::forward<Args>(args)...);
1641  }
1642 #endif
1643 
1644  /**
1645  * This is a wrapper which takes a pointer to a function which
1646  * returns a value, together with arguments, and constructs a
1647  * TaskManager task which will execute that function by calling
1648  * add_task() with an appropriate callback object, and returns a
1649  * Cgu::AsyncResult object (held by Cgu::SharedLockPtr) which will
1650  * provide the value that the function returns. Apart from the
1651  * absence of a 'one thread per task' model, this method therefore
1652  * provides a similar interface to the one provided by
1653  * Cgu::Thread::Future. It is thread safe: any thread may call this
1654  * method, including another task running on the TaskManager object,
1655  * but see the introductory remarks about the use of the
1656  * TaskManager::IncHandle scoped handle class where a task running on
1657  * a TaskManager object is to block on one of its sub-tasks. See
1658  * also the documentation on add_task() for further information about
1659  * how task execution works.
1660  *
1661  * This method can take up to four bound arguments for the target
1662  * function.
1663  *
1664  * If the function passed to this method exits by throwing
1665  * Thread::Exit or some other exception, then the exception will be
1666  * consumed and the returned Cgu::AsyncResult object's get() or
1667  * move_get() method will unblock and its get_error() method will
1668  * return -1.
1669  *
1670  * @param func The function to be executed as a task.
1671  * @param args The arguments to be passed to that function.
1672  * @exception std::bad_alloc This exception will be thrown if memory
1673  * is exhausted and the system throws in that case. (On systems with
1674  * over-commit/lazy-commit combined with virtual memory (swap), it is
1675  * rarely useful to check for memory exhaustion). See also the
1676  * documentation for the get_max_tasks() method about the possibility
1677  * of std::length_error being thrown. If std::bad_alloc or
1678  * std::length_error is thrown, the task will not start.
1679  * @exception Cgu::Thread::TaskError This exception will be thrown if
1680  * stop_all() has previously been called. It will also be thrown if
1681  * is_error() would return true because this class's internal thread
1682  * pool loop implementation has thrown std::bad_alloc, or a thread
1683  * has failed to start correctly. (On systems with
1684  * over-commit/lazy-commit combined with virtual memory (swap), it is
1685  * rarely useful to check for memory exhaustion, but there may be
1686  * some specialized cases where the return value of is_error() is
1687  * useful.) If this exception is thrown, the task will not start.
1688  * @note This method will also throw if the copy or move constructor
1689  * of a bound argument throws. If such an exception is thrown, the
1690  * task will not start.
1691  *
1692  * Since 2.0.13
1693  */
1694  template <class Ret, class... Params, class... Args>
1696  Args&&... args);
1697 
1698  /**
1699  * This is a wrapper which takes a pointer to a function which
1700  * returns a value, together with arguments, and constructs a
1701  * TaskManager task which will execute that function by calling
1702  * add_task() with an appropriate callback object, and causes the
1703  * 'when' callback passed as an argument to this method to be
1704  * executed by a glib main loop if and when the task finishes
1705  * correctly - the 'when' callback is passed the function's return
1706  * value when it is invoked. It is thread safe (any thread may call
1707  * this method, including another task running on the TaskManager
1708  * object). Apart from the absence of a 'one thread per task' model,
1709  * this method therefore provides a similar interface to the one
1710  * provided by Cgu::Thread::Future. See the documentation on
1711  * add_task() for further information about how task execution works.
1712  *
1713  * This method can take up to four bound arguments for the target
1714  * function.
1715  *
1716  * Note that unlike add_task(), but like the 'fail' callback of
1717  * Cgu::Thread::Future objects, if a fail callback is provided to
1718  * this method and it executes, it will execute in the glib main loop
1719  * whose GMainContext object is passed to the 'context' argument of
1720  * this method.
1721  *
1722  * Note also that if releasers are provided for the 'when' or 'fail'
1723  * callbacks, these are passed by pointer and not by reference (this
1724  * is so that a NULL pointer can indicate that no releaser is to be
1725  * provided). If provided, a releaser will enable automatic
1726  * disconnection of the 'when' or 'fail' callback, if the object of
1727  * which the releaser is a member is destroyed. For this to be race
1728  * free, the lifetime of that object must be controlled by the thread
1729  * in whose main loop the 'when' or 'fail' callback will execute.
1730  *
1731  * The make_task_when() method is similar to this method but provides
1732  * an abbreviated set of paramaters suitable for most cases. This
1733  * method is for use where releasers or a 'fail' callback are
1734  * required.
1735  *
1736  * @param when A callback which will be executed if and when the
1737  * function passed to this method finishes correctly. The callback is
1738  * passed that function's return value when it is invoked. If an
1739  * exception propagates from the 'when' callback, this will be
1740  * consumed and a g_critical() warning will be issued. The callback
1741  * will execute in the glib main loop whose GMainContext object is
1742  * passed to the 'context' argument of this method.
1743  * @param when_releaser A pointer to a Releaser object for automatic
1744  * disconnection of the 'when' callback before it executes in a main
1745  * loop (mainly relevant if the callback represents a non-static
1746  * member function of an object which may be destroyed before the
1747  * callback executes). A value of 0/NULL/nullptr indicates no
1748  * releaser.
1749  * @param fail A callback which will be executed if the 'when'
1750  * callback does not execute. This would happen if the function
1751  * passed to this method exits by throwing Thread::Exit or some other
1752  * exception, if the copy constructor of a non-reference argument of
1753  * that function throws, if the move constructor (or if it has none,
1754  * the copy constructor) of that function's return value throws or if
1755  * the 'when' callback does not execute because the internal
1756  * implementation of this wrapper throws std::bad_alloc (which will
1757  * not happen if the library has been installed using the
1758  * \--with-glib-memory-slices-no-compat configuration option: instead
1759  * glib will terminate the program if it is unable to obtain memory
1760  * from the operating system). If an exception propagates from the
1761  * 'fail' callback, this will be consumed and a g_critical() warning
1762  * will be issued. The callback will execute in the glib main loop
1763  * whose GMainContext object is passed to the 'context' argument of
1764  * this method. An empty std::unique_ptr object indicates no 'fail'
1765  * callback.
1766  * @param fail_releaser A pointer to a Releaser object for automatic
1767  * disconnection of the 'fail' callback before it executes in a main
1768  * loop (mainly relevant if the callback represents a non-static
1769  * member function of an object which may be destroyed before the
1770  * callback executes). A value of 0/NULL/nullptr indicates no
1771  * releaser.
1772  * @param priority The priority to be given in the main loop to the
1773  * 'when' callback or any 'fail' callback. In ascending order of
1774  * priorities, priorities are G_PRIORITY_LOW,
1775  * G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT
1776  * and G_PRIORITY_HIGH. This determines the order in which the
1777  * callback will appear in the event list in the main loop, not the
1778  * priority which the OS will adopt.
1779  * @param context The glib main context of the main loop in which the
1780  * 'when' callback or any 'fail' callback is to be executed. A value
1781  * 0/NULL/nullptr will cause the callback to be executed in the main
1782  * program loop.
1783  * @param func The function to be executed as a task. If an
1784  * exception propagates from the task, the exception will be consumed
1785  * and the 'fail' callback will execute.
1786  * @param args The arguments to be passed to that function.
1787  * @exception std::bad_alloc This exception will be thrown if memory
1788  * is exhausted and the system throws in that case. (On systems with
1789  * over-commit/lazy-commit combined with virtual memory (swap), it is
1790  * rarely useful to check for memory exhaustion). See also the
1791  * documentation for the get_max_tasks() method about the possibility
1792  * of std::length_error being thrown. If std::bad_alloc or
1793  * std::length_error If this exception is thrown, the task will not
1794  * start (which also means that the 'when' and 'fail' callbacks will
1795  * not execute).
1796  * @exception Cgu::Thread::TaskError This exception will be thrown if
1797  * stop_all() has previously been called. It will also be thrown if
1798  * is_error() would return true because this class's internal thread
1799  * pool loop implementation has thrown std::bad_alloc, or a thread
1800  * has failed to start correctly. (On systems with
1801  * over-commit/lazy-commit combined with virtual memory (swap), it is
1802  * rarely useful to check for memory exhaustion, but there may be
1803  * some specialized cases where the return value of is_error() is
1804  * useful.) If this exception is thrown, the task will not start
1805  * (which also means that the 'when' and 'fail' callbacks will not
1806  * execute).
1807  * @note 1. This method will also throw if the copy or move
1808  * constructor of a bound argument throws. If such an exception is
1809  * thrown, the task will not start (which also means that the 'when'
1810  * and 'fail' callbacks will not execute).
1811  * @note 2. If a 'when_releaser' or a 'fail_releaser' object is
1812  * provided, it is in theory possible (if memory is exhausted and the
1813  * system throws in that case) that an internal SafeEmitterArg object
1814  * will throw std::bad_alloc when emitting/executing the 'when' or
1815  * 'fail' callback in the glib main loop, with the result that the
1816  * relevant callback will not execute (instead the exception will be
1817  * consumed and a g_critical() warning will be issued). This is
1818  * rarely of any relevance because glib will abort the program if it
1819  * is itself unable to obtain memory from the operating system.
1820  * However, where it is relevant, design the program so that it is
1821  * not necessary to provide a releaser object.
1822  * @note 3. If the library is compiled using the \--with-auto-ptr
1823  * configuration option, then this method uses std::auto_ptr in place
1824  * of std::unique_ptr in its signature in order to retain
1825  * compatibility with the 1.2 series of the library.
1826  *
1827  * Since 2.0.13
1828  */
1829  template <class Ret, class... Params, class... Args>
1830 #ifdef CGU_USE_AUTO_PTR
1831  void make_task_when_full(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1832  Cgu::Releaser* when_releaser,
1833  std::auto_ptr<const Cgu::Callback::Callback> fail,
1834  Cgu::Releaser* fail_releaser,
1835  gint priority,
1836  GMainContext* context,
1837  Ret (*func)(Params...),
1838  Args&&... args);
1839 #else
1840  void make_task_when_full(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1841  Cgu::Releaser* when_releaser,
1842  std::unique_ptr<const Cgu::Callback::Callback> fail,
1843  Cgu::Releaser* fail_releaser,
1844  gint priority,
1845  GMainContext* context,
1846  Ret (*func)(Params...),
1847  Args&&... args);
1848 #endif
1849 
1850  /**
1851  * This is an abbreviated version of make_task_when_full(), which is
1852  * for use when it is known that invocation of the function passed to
1853  * this method, the copy constructors of any non-reference arguments
1854  * of that function and the move constructor (or if it has none, the
1855  * copy constructor) of that function's return value do not throw
1856  * anything other than std::bad_alloc, and the user is not interested
1857  * in std::bad_alloc and does not need a Cgu::Releaser object for the
1858  * 'when' callback (which is likely to cover the majority of uses,
1859  * particularly when composing tasks using glib because glib
1860  * terminates the program if it is unable to obtain memory).
1861  *
1862  * This method can take up to four bound arguments for the target
1863  * function.
1864  *
1865  * Like make_task_when_full(), this method is a wrapper which takes a
1866  * pointer to a function which returns a value, together with
1867  * arguments, and constructs a TaskManager task which will execute
1868  * that function by calling add_task() with an appropriate callback
1869  * object, and causes the 'when' callback passed as an argument to
1870  * this method to be executed by a glib main loop if and when the
1871  * task finishes correctly - the 'when' callback is passed the
1872  * function's return value when it is invoked. It is thread safe
1873  * (any thread may call this method, including another task running
1874  * on the TaskManager object). Apart from the absence of a 'one
1875  * thread per task' model, this method therefore provides a similar
1876  * interface to the one provided by Cgu::Thread::Future. See the
1877  * documentation on add_task() for further information about how task
1878  * execution works.
1879  *
1880  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
1881  * in the main loop.
1882  *
1883  * @param when A callback which will be executed if and when the
1884  * function passed to this method finishes correctly. The callback is
1885  * passed that function's return value when it is invoked. If an
1886  * exception propagates from the 'when' callback, this will be
1887  * consumed and a g_critical() warning will be issued. The callback
1888  * will execute in the glib main loop whose GMainContext object is
1889  * passed to the 'context' argument of this method.
1890  * @param context The glib main context of the main loop in which the
1891  * 'when' callback is to be executed. A value 0/NULL/nullptr will
1892  * cause the callback to be executed in the main program loop.
1893  * @param func The function to be executed as a task. If an
1894  * exception propagates from the task, the exception will be consumed
1895  * and (if the thrown object's type is not Cgu::Thread::Exit) a
1896  * g_critical() warning will be issued.
1897  * @param args The arguments to be passed to that function.
1898  * @exception std::bad_alloc This exception will be thrown if memory
1899  * is exhausted and the system throws in that case. (On systems with
1900  * over-commit/lazy-commit combined with virtual memory (swap), it is
1901  * rarely useful to check for memory exhaustion). See also the
1902  * documentation for the get_max_tasks() method about the possibility
1903  * of std::length_error being thrown. If std::bad_alloc or
1904  * std::length_error is thrown, the task will not start (which also
1905  * means that the 'when' callback will not execute).
1906  * @exception Cgu::Thread::TaskError This exception will be thrown if
1907  * stop_all() has previously been called. It will also be thrown if
1908  * is_error() would return true because this class's internal thread
1909  * pool loop implementation has thrown std::bad_alloc, or a thread
1910  * has failed to start correctly. (On systems with
1911  * over-commit/lazy-commit combined with virtual memory (swap), it is
1912  * rarely useful to check for memory exhaustion, but there may be
1913  * some specialized cases where the return value of is_error() is
1914  * useful.) If this exception is thrown, the task will not start
1915  * (which also means that the 'when' callback will not execute).
1916  * @note 1. This method will also throw if the copy or move
1917  * constructor of a bound argument throws. If such an exception is
1918  * thrown, the task will not start (which also means that the 'when'
1919  * callback will not execute).
1920  * @note 2. If the library is compiled using the \--with-auto-ptr
1921  * configuration option, then this method uses std::auto_ptr in place
1922  * of std::unique_ptr in its signature in order to retain
1923  * compatibility with the 1.2 series of the library.
1924  * @note 3. As mentioned in describing 'func' above, if 'func' exits
1925  * by throwing an exception the exception will be consumed and (if
1926  * the thrown object's type is not Cgu::Thread::Exit) a g_critical()
1927  * warning will be issued. The same will occur if the copy
1928  * constructor of a non-reference argument of 'func' throws when
1929  * invoking 'func' or the move constructor (or if it has none, the
1930  * copy constructor) of the return value of 'func' throws, or if the
1931  * internal implementation of this wrapper throws std::bad_alloc on
1932  * executing 'func'.
1933  *
1934  * Since 2.0.13
1935  */
1936  template <class Ret, class... Params, class... Args>
1937 #ifdef CGU_USE_AUTO_PTR
1938  void make_task_when(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1939  GMainContext* context,
1940  Ret (*func)(Params...),
1941  Args&&... args) {
1942  static_assert(sizeof...(Args) < 5,
1943  "No greater than four bound arguments can be passed to "
1944  "TaskManager::make_task_when() taking a function.");
1945 
1946  make_task_when_full(when,
1947  0,
1948  std::auto_ptr<const Cgu::Callback::Callback>(),
1949  0,
1950  G_PRIORITY_DEFAULT,
1951  context,
1952  func,
1953  std::forward<Args>(args)...);
1954 #else
1955  void make_task_when(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
1956  GMainContext* context,
1957  Ret (*func)(Params...),
1958  Args&&... args) {
1959  static_assert(sizeof...(Args) < 5,
1960  "No greater than four bound arguments can be passed to "
1961  "TaskManager::make_task_when() taking a function.");
1962 
1963  make_task_when_full(std::move(when),
1964  0,
1965  std::unique_ptr<const Cgu::Callback::Callback>(),
1966  0,
1967  G_PRIORITY_DEFAULT,
1968  context,
1969  func,
1970  std::forward<Args>(args)...);
1971 #endif
1972  }
1973 
1974  /**
1975  * This is a wrapper which takes a callable object which returns a
1976  * value (such as a std::function object, a lambda or the return
1977  * value of std::bind), and constructs a TaskManager task which will
1978  * execute that object by calling add_task() with an appropriate
1979  * callback object, and returns a Cgu::AsyncResult object (held by
1980  * Cgu::SharedLockPtr) which will provide the value that it returns.
1981  * Apart from the absence of a 'one thread per task' model, this
1982  * method therefore provides a similar interface to the one provided
1983  * by Cgu::Thread::Future. It is thread safe: any thread may call
1984  * this method, including another task running on the TaskManager
1985  * object, but see the introductory remarks about the use of the
1986  * TaskManager::IncHandle scoped handle class where a task running on
1987  * a TaskManager object is to block on one of its sub-tasks. See
1988  * also the documentation on add_task() for further information about
1989  * how task execution works.
1990  *
1991  * From version 2.0.14, this method takes the callable object as a
1992  * template parameter, and in version 2.0.13 it took it as a
1993  * std::function object. In version 2.0.13 it was necessary to
1994  * specify the return value of any callable object which was not a
1995  * std::function object as a specific template parameter: this is not
1996  * necessary from version 2.0.14, as it is deduced automatically.
1997  *
1998  * If the callable object passed to this method exits by throwing
1999  * Thread::Exit or some other exception, then the exception will be
2000  * consumed and the returned Cgu::AsyncResult object's get() or
2001  * move_get() method will unblock and its get_error() method will
2002  * return -1.
2003  *
2004  * @param f The callable object to be executed as a task. It should
2005  * return a value (it cannot return void).
2006  * @exception std::bad_alloc This exception will be thrown if memory
2007  * is exhausted and the system throws in that case. (On systems with
2008  * over-commit/lazy-commit combined with virtual memory (swap), it is
2009  * rarely useful to check for memory exhaustion). See also the
2010  * documentation for the get_max_tasks() method about the possibility
2011  * of std::length_error being thrown. If std::bad_alloc or
2012  * std::length_error is thrown, the task will not start.
2013  * @exception Cgu::Thread::TaskError This exception will be thrown if
2014  * stop_all() has previously been called. It will also be thrown if
2015  * is_error() would return true because this class's internal thread
2016  * pool loop implementation has thrown std::bad_alloc, or a thread
2017  * has failed to start correctly. (On systems with
2018  * over-commit/lazy-commit combined with virtual memory (swap), it is
2019  * rarely useful to check for memory exhaustion, but there may be
2020  * some specialized cases where the return value of is_error() is
2021  * useful.) If this exception is thrown, the task will not start.
2022  * @note 1. This method will also throw if the copy or move
2023  * constructor of the callable object throws. If such an exception
2024  * is thrown, the task will not start.
2025  * @note 2. If the callable object passed as an argument has both
2026  * const and non-const operator()() methods, the non-const version
2027  * will be called even if the callable object passed is a const
2028  * object.
2029  *
2030  * Since 2.0.13
2031  */
2032  // we don't need this version of make_task_result() for syntactic
2033  // reasons - the version taking a single template parameter will do
2034  // by itself syntactically because it can use decltype. However, we
2035  // include this version in order to be API compatible with
2036  // c++-gtk-utils < 2.0.14, which required the return type to be
2037  // specified when this method is passed something other than a
2038  // std::function object. SFINAE will take care of the rest, except
2039  // with a corner case where all of the following apply: (i) a
2040  // function object is passed whose operator()() method returns a
2041  // copy of the function object (or another function object of the
2042  // same type), (ii) the function object is passed to this method as
2043  // a rvalue and not a lvalue, and (iii) the user specifically states
2044  // the return type when instantiating this template function. This
2045  // would give rise to an ambiguity, but its happening is extremely
2046  // unlikely, and cannot happen with a lambda or the return value of
2047  // std::bind, because those types are only known to the compiler,
2048  // and cannot happen with other objects if the user lets template
2049  // deduction take its course.
2050  template <class Ret, class Func>
2052 
2053  // we don't want to document this function: it provides the type
2054  // deduction of the return value of the passed functor (it deals
2055  // with cases where this is not specified expressly).
2056 #ifndef DOXYGEN_PARSING
2057  template <class Func>
2059 
2060  // TODO: this is a work-around for gcc < 4.7, which has a bug
2061  // which requires a function whose return value is determined by
2062  // decltype, such as make_task_result(Func&&), to be inline. At a
2063  // suitable API/ABI break when gcc requirements are updated, this
2064  // should be moved to task_manager.tpp.
2065 
2066  // there are two types related to the functor to be executed by
2067  // the task. 'Func' is the transient type provided by argument
2068  // deduction for forwarding, and will vary depending on whether
2069  // the functor object is a lvalue (which will deduce it as a
2070  // reference type) or rvalue (which will not). 'FType' is the
2071  // type to be held by the callback object generated in this
2072  // function, and is never a reference type. It is also never
2073  // const, because the FType member is marked mutable in the
2074  // callback object so that it can execute mutable lambdas (or
2075  // other functors with a non-const operator()() method).
2076  typedef typename std::remove_const<typename std::remove_reference<Func>::type>::type FType;
2077  // this method will fail to compile if Ret is a reference type:
2078  // that is a feature, not a bug, as a function returning a
2079  // reference lacks referential transparency, is unlikely to be
2080  // thread-safe and is unsuitable for use as a task function
2081  typedef decltype(f()) Ret;
2082 #ifdef CGU_USE_AUTO_PTR
2083  typedef std::auto_ptr<const Callback::Callback> CbPtr;
2084 #else
2085  typedef std::unique_ptr<const Callback::Callback> CbPtr;
2086 #endif
2087 
2089  CbPtr exec_cb(new TaskManagerHelper2::FunctorResultExec<Ret, FType>(std::forward<Func>(f), ret));
2090  CbPtr do_fail_cb(Callback::make_ref(&TaskManagerHelper2::FunctorResultWrapper<Ret, FType>::do_fail,
2091  ret));
2092  add_task(std::move(exec_cb), std::move(do_fail_cb));
2093 
2094  return ret;
2095  }
2096 #endif
2097 
2098  /**
2099  * This is a wrapper which takes a callable object which returns a
2100  * value (such as a std::function object, a lambda or the return
2101  * value of std::bind), and constructs a TaskManager task which will
2102  * execute that object by calling add_task() with an appropriate
2103  * callback object, and causes the 'when' callback passed as an
2104  * argument to this method to be executed by a glib main loop if and
2105  * when the task finishes correctly - the 'when' callback is passed
2106  * the callable object's return value when it is invoked. It is
2107  * thread safe (any thread may call this method, including another
2108  * task running on the TaskManager object). Apart from the absence
2109  * of a 'one thread per task' model, this method therefore provides a
2110  * similar interface to the one provided by Cgu::Thread::Future. See
2111  * the documentation on add_task() for further information about how
2112  * task execution works.
2113  *
2114  * From version 2.0.14, this method takes the callable object as a
2115  * template parameter, and in version 2.0.13 it took it as a
2116  * std::function object. In version 2.0.13 it was necessary to
2117  * specify the return value of any callable object which was not a
2118  * std::function object as a specific template parameter: this is not
2119  * necessary from version 2.0.14, as it is deduced automatically.
2120  *
2121  * Note that unlike add_task(), but like the 'fail' callback of
2122  * Cgu::Thread::Future objects, if a fail callback is provided to
2123  * this method and it executes, it will execute in the glib main loop
2124  * whose GMainContext object is passed to the 'context' argument of
2125  * this method.
2126  *
2127  * Note also that if releasers are provided for the 'when' or 'fail'
2128  * callbacks, these are passed by pointer and not by reference (this
2129  * is so that a NULL pointer can indicate that no releaser is to be
2130  * provided). If provided, a releaser will enable automatic
2131  * disconnection of the 'when' or 'fail' callback, if the object of
2132  * which the releaser is a member is destroyed. For this to be race
2133  * free, the lifetime of that object must be controlled by the thread
2134  * in whose main loop the 'when' or 'fail' callback will execute.
2135  *
2136  * The make_task_when() method is similar to this method but provides
2137  * an abbreviated set of paramaters suitable for most cases. This
2138  * method is for use where releasers or a 'fail' callback are
2139  * required.
2140  *
2141  * @param when A callback which will be executed if and when the
2142  * callable object passed as 'func' to this method finishes
2143  * correctly. The callback is passed that object's return value when
2144  * it is invoked. If an exception propagates from the 'when'
2145  * callback, this will be consumed and a g_critical() warning will be
2146  * issued. The callback will execute in the glib main loop whose
2147  * GMainContext object is passed to the 'context' argument of this
2148  * method.
2149  * @param when_releaser A pointer to a Releaser object for automatic
2150  * disconnection of the 'when' callback before it executes in a main
2151  * loop (mainly relevant if the callback represents a non-static
2152  * member function of an object which may be destroyed before the
2153  * callback executes). A value of 0/NULL/nullptr indicates no
2154  * releaser.
2155  * @param fail A callback which will be executed if the 'when'
2156  * callback does not execute. This would happen if the callable
2157  * object passed as 'func' to this method exits by throwing
2158  * Thread::Exit or some other exception, if the move constructor (or
2159  * if it has none, the copy constructor) of that object's return
2160  * value throws or if the 'when' callback does not execute because
2161  * the internal implementation of this wrapper throws std::bad_alloc
2162  * (which will not happen if the library has been installed using the
2163  * \--with-glib-memory-slices-no-compat configuration option: instead
2164  * glib will terminate the program if it is unable to obtain memory
2165  * from the operating system). If an exception propagates from the
2166  * 'fail' callback, this will be consumed and a g_critical() warning
2167  * will be issued. The callback will execute in the glib main loop
2168  * whose GMainContext object is passed to the 'context' argument of
2169  * this method. An empty std::unique_ptr object indicates no 'fail'
2170  * callback.
2171  * @param fail_releaser A pointer to a Releaser object for automatic
2172  * disconnection of the 'fail' callback before it executes in a main
2173  * loop (mainly relevant if the callback represents a non-static
2174  * member function of an object which may be destroyed before the
2175  * callback executes). A value of 0/NULL/nullptr indicates no
2176  * releaser.
2177  * @param priority The priority to be given in the main loop to the
2178  * 'when' callback or any 'fail' callback. In ascending order of
2179  * priorities, priorities are G_PRIORITY_LOW,
2180  * G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE, G_PRIORITY_DEFAULT
2181  * and G_PRIORITY_HIGH. This determines the order in which the
2182  * callback will appear in the event list in the main loop, not the
2183  * priority which the OS will adopt.
2184  * @param context The glib main context of the main loop in which the
2185  * 'when' callback or any 'fail' callback is to be executed. A value
2186  * 0/NULL/nullptr will cause the callback to be executed in the main
2187  * program loop.
2188  * @param func The callable object to be executed as a task, such as
2189  * formed by a lambda expression or the result of std::bind. It
2190  * should return a value (it cannot return void). It must be fully
2191  * bound (that is, it must take no arguments when called). If an
2192  * exception propagates from the task, the exception will be consumed
2193  * and the 'fail' callback will execute.
2194  * @exception std::bad_alloc This exception will be thrown if memory
2195  * is exhausted and the system throws in that case. (On systems with
2196  * over-commit/lazy-commit combined with virtual memory (swap), it is
2197  * rarely useful to check for memory exhaustion). See also the
2198  * documentation for the get_max_tasks() method about the possibility
2199  * of std::length_error being thrown. If std::bad_alloc or
2200  * std::length_error is thrown, the task will not start (which also
2201  * means that the 'when' and 'fail' callbacks will not execute).
2202  * @exception Cgu::Thread::TaskError This exception will be thrown if
2203  * stop_all() has previously been called. It will also be thrown if
2204  * is_error() would return true because this class's internal thread
2205  * pool loop implementation has thrown std::bad_alloc, or a thread
2206  * has failed to start correctly. (On systems with
2207  * over-commit/lazy-commit combined with virtual memory (swap), it is
2208  * rarely useful to check for memory exhaustion, but there may be
2209  * some specialized cases where the return value of is_error() is
2210  * useful.) If this exception is thrown, the task will not start
2211  * (which also means that the 'when' and 'fail' callbacks will not
2212  * execute).
2213  * @note 1. This method will also throw if the copy or move
2214  * constructor of the callable object throws. If such an exception
2215  * is thrown, the task will not start (which also means that the
2216  * 'when' and 'fail' callbacks will not execute).
2217  * @note 2. If the callable object passed as an argument has both
2218  * const and non-const operator()() methods, the non-const version
2219  * will be called even if the callable object passed is a const
2220  * object.
2221  * @note 3. If a 'when_releaser' or a 'fail_releaser' object is
2222  * provided, it is in theory possible (if memory is exhausted and the
2223  * system throws in that case) that an internal SafeEmitterArg object
2224  * will throw std::bad_alloc when emitting/executing the 'when' or
2225  * 'fail' callback in the glib main loop, with the result that the
2226  * relevant callback will not execute (instead the exception will be
2227  * consumed and a g_critical() warning will be issued). This is
2228  * rarely of any relevance because glib will abort the program if it
2229  * is itself unable to obtain memory from the operating system.
2230  * However, where it is relevant, design the program so that it is
2231  * not necessary to provide a releaser object.
2232  * @note 4. If the library is compiled using the \--with-auto-ptr
2233  * configuration option, then this method uses std::auto_ptr in place
2234  * of std::unique_ptr in its signature in order to retain
2235  * compatibility with the 1.2 series of the library.
2236  *
2237  * Since 2.0.13
2238  */
2239  template <class Ret, class Func>
2240 #ifdef CGU_USE_AUTO_PTR
2241  void make_task_when_full(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
2242  Cgu::Releaser* when_releaser,
2243  std::auto_ptr<const Cgu::Callback::Callback> fail,
2244  Cgu::Releaser* fail_releaser,
2245  gint priority,
2246  GMainContext* context,
2247  Func&& func);
2248 #else
2249  void make_task_when_full(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
2250  Cgu::Releaser* when_releaser,
2251  std::unique_ptr<const Cgu::Callback::Callback> fail,
2252  Cgu::Releaser* fail_releaser,
2253  gint priority,
2254  GMainContext* context,
2255  Func&& func);
2256 #endif
2257 
2258  /**
2259  * This is an abbreviated version of make_task_when_full(), which is
2260  * for use when it is known that invocation of the callable object
2261  * passed to this method and the move constructor (or if it has none,
2262  * the copy constructor) of that object's return value do not throw
2263  * anything other than std::bad_alloc, and the user is not interested
2264  * in std::bad_alloc and does not need a Cgu::Releaser object for the
2265  * 'when' callback (which is likely to cover the majority of uses,
2266  * particularly when composing tasks using glib because glib
2267  * terminates the program if it is unable to obtain memory).
2268  *
2269  * From version 2.0.14, this method takes the callable object as a
2270  * template parameter, and in version 2.0.13 it took it as a
2271  * std::function object. In version 2.0.13 it was necessary to
2272  * specify the return value of any callable object which was not a
2273  * std::function object as a specific template parameter: this is not
2274  * necessary from version 2.0.14, as it is deduced automatically.
2275  *
2276  * Like make_task_when_full(), this method is a wrapper which takes a
2277  * callable object which returns a value, and constructs a
2278  * TaskManager task which will execute that object by calling
2279  * add_task() with an appropriate callback object, and causes the
2280  * 'when' callback passed as an argument to this method to be
2281  * executed by a glib main loop if and when the task finishes
2282  * correctly - the 'when' callback is passed the callable object's
2283  * return value when it is invoked. It is thread safe (any thread
2284  * may call this method, including another task running on the
2285  * TaskManager object). Apart from the absence of a 'one thread per
2286  * task' model, this method therefore provides a similar interface to
2287  * the one provided by Cgu::Thread::Future. See the documentation on
2288  * add_task() for further information about how task execution works.
2289  *
2290  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
2291  * in the main loop.
2292  *
2293  * There is a similar make_task_compose() function which has the
2294  * callable object to be executed as a task as its first argument and
2295  * the 'when' callback as its last argument, in order to aid task
2296  * composition.
2297  *
2298  * @param when A callback which will be executed if and when the
2299  * callable object passed to this method finishes correctly. The
2300  * callback is passed that object's return value when it is invoked.
2301  * If an exception propagates from the 'when' callback, this will be
2302  * consumed and a g_critical() warning will be issued. The callback
2303  * will execute in the glib main loop whose GMainContext object is
2304  * passed to the 'context' argument of this method.
2305  * @param context The glib main context of the main loop in which the
2306  * 'when' callback is to be executed. A value 0/NULL/nullptr will
2307  * cause the callback to be executed in the main program loop.
2308  * @param f The callable object to be executed as a task, such as
2309  * formed by a lambda expression or the result of std::bind. It
2310  * should return a value (it cannot return void). It must be fully
2311  * bound (that is, it must take no arguments when called). If an
2312  * exception propagates from the task, the exception will be consumed
2313  * and (if the thrown object's type is not Cgu::Thread::Exit) a
2314  * g_critical() warning will be issued.
2315  * @exception std::bad_alloc This exception will be thrown if memory
2316  * is exhausted and the system throws in that case. (On systems with
2317  * over-commit/lazy-commit combined with virtual memory (swap), it is
2318  * rarely useful to check for memory exhaustion). See also the
2319  * documentation for the get_max_tasks() method about the possibility
2320  * of std::length_error being thrown. If std::bad_alloc or
2321  * std::length_error is thrown, the task will not start (which also
2322  * means that the 'when' callback will not execute).
2323  * @exception Cgu::Thread::TaskError This exception will be thrown if
2324  * stop_all() has previously been called. It will also be thrown if
2325  * is_error() would return true because this class's internal thread
2326  * pool loop implementation has thrown std::bad_alloc, or a thread
2327  * has failed to start correctly. (On systems with
2328  * over-commit/lazy-commit combined with virtual memory (swap), it is
2329  * rarely useful to check for memory exhaustion, but there may be
2330  * some specialized cases where the return value of is_error() is
2331  * useful.) If this exception is thrown, the task will not start
2332  * (which also means that the 'when' callback will not execute).
2333  * @note 1. This method will also throw if the copy or move
2334  * constructor of the callable object throws. If such an exception
2335  * is thrown, the task will not start (which also means that the
2336  * 'when' callback will not execute).
2337  * @note 2. If the callable object passed as an argument has both
2338  * const and non-const operator()() methods, the non-const version
2339  * will be called even if the callable object passed is a const
2340  * object.
2341  * @note 3. If the library is compiled using the \--with-auto-ptr
2342  * configuration option, then this method uses std::auto_ptr in place
2343  * of std::unique_ptr in its signature in order to retain
2344  * compatibility with the 1.2 series of the library.
2345  * @note 4. As mentioned in describing 'f' above, if 'f' exits by
2346  * throwing an exception the exception will be consumed and (if the
2347  * thrown object's type is not Cgu::Thread::Exit) a g_critical()
2348  * warning will be issued. The same will occur if the move
2349  * constructor (or if it has none, the copy constructor) of the
2350  * return value of 'f' throws or if the internal implementation of
2351  * this wrapper throws std::bad_alloc on executing 'f'.
2352  *
2353  * Since 2.0.13
2354  */
2355  template <class Ret, class Func>
2356 #ifdef CGU_USE_AUTO_PTR
2357  void make_task_when(std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
2358  GMainContext* context,
2359  Func&& f) {
2360  make_task_when_full(when,
2361  0,
2362  std::auto_ptr<const Cgu::Callback::Callback>(),
2363  0,
2364  G_PRIORITY_DEFAULT,
2365  context,
2366  std::forward<Func>(f));
2367  }
2368 #else
2369  void make_task_when(std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when,
2370  GMainContext* context,
2371  Func&& f) {
2372  make_task_when_full(std::move(when),
2373  0,
2374  std::unique_ptr<const Cgu::Callback::Callback>(),
2375  0,
2376  G_PRIORITY_DEFAULT,
2377  context,
2378  std::forward<Func>(f));
2379  }
2380 #endif
2381 
2382  /**
2383  * This is an abbreviated version of make_task_when_full(), which is
2384  * for use when it is known that invocation of the callable object
2385  * passed to this method and the move constructor (or if it has none,
2386  * the copy constructor) of that object's return value do not throw
2387  * anything other than std::bad_alloc, and the user is not interested
2388  * in std::bad_alloc and does not need a Cgu::Releaser object for the
2389  * 'when' callback (which is likely to cover the majority of uses,
2390  * particularly when composing tasks using glib because glib
2391  * terminates the program if it is unable to obtain memory).
2392  *
2393  * From version 2.0.14, this method takes the callable object as a
2394  * template parameter, and in version 2.0.13 it took it as a
2395  * std::function object. In version 2.0.13 it was necessary to
2396  * specify the return value of any callable object which was not a
2397  * std::function object as a specific template parameter: this is not
2398  * necessary from version 2.0.14, as it is deduced automatically.
2399  *
2400  * This method does the same as the version of make_task_when()
2401  * taking a callable object, except that this method takes that
2402  * object as its first argument and the 'when' callback as its last
2403  * argument in order to aid task composition, and in particular so
2404  * tasks compose in user code in a visually ordered manner.
2405  *
2406  * More particularly, like make_task_when_full(), this method is a
2407  * wrapper which takes a callable object which returns a value, and
2408  * constructs a TaskManager task which will execute that object by
2409  * calling add_task() with an appropriate callback object, and causes
2410  * the 'when' callback passed as an argument to this method to be
2411  * executed by a glib main loop if and when the task finishes
2412  * correctly - the 'when' callback is passed the callable object's
2413  * return value when it is invoked. It is thread safe (any thread
2414  * may call this method, including another task running on the
2415  * TaskManager object). Apart from the absence of a 'one thread per
2416  * task' model, this method therefore provides a similar interface to
2417  * the one provided by Cgu::Thread::Future. See the documentation on
2418  * add_task() for further information about how task execution works.
2419  *
2420  * The 'when' callback will execute with G_PRIORITY_DEFAULT priority
2421  * in the main loop.
2422  *
2423  * @param f The callable object to be executed as a task, such as
2424  * formed by a lambda expression or the result of std::bind. It
2425  * should return a value (it cannot return void). It must be fully
2426  * bound (that is, it must take no arguments when called). If an
2427  * exception propagates from the task, the exception will be consumed
2428  * and (if the thrown object's type is not Cgu::Thread::Exit) a
2429  * g_critical() warning will be issued.
2430  * @param context The glib main context of the main loop in which the
2431  * 'when' callback is to be executed. A value 0/NULL/nullptr will
2432  * cause the callback to be executed in the main program loop.
2433  * @param when A callback which will be executed if and when the
2434  * callable object passed to this method finishes correctly. The
2435  * callback is passed that object's return value when it is invoked.
2436  * If an exception propagates from the 'when' callback, this will be
2437  * consumed and a g_critical() warning will be issued. The callback
2438  * will execute in the glib main loop whose GMainContext object is
2439  * passed to the 'context' argument of this method.
2440  * @exception std::bad_alloc This exception will be thrown if memory
2441  * is exhausted and the system throws in that case. (On systems with
2442  * over-commit/lazy-commit combined with virtual memory (swap), it is
2443  * rarely useful to check for memory exhaustion). See also the
2444  * documentation for the get_max_tasks() method about the possibility
2445  * of std::length_error being thrown. If std::bad_alloc or
2446  * std::length_error is thrown, the task will not start (which also
2447  * means that the 'when' callback will not execute).
2448  * @exception Cgu::Thread::TaskError This exception will be thrown if
2449  * stop_all() has previously been called. It will also be thrown if
2450  * is_error() would return true because this class's internal thread
2451  * pool loop implementation has thrown std::bad_alloc, or a thread
2452  * has failed to start correctly. (On systems with
2453  * over-commit/lazy-commit combined with virtual memory (swap), it is
2454  * rarely useful to check for memory exhaustion, but there may be
2455  * some specialized cases where the return value of is_error() is
2456  * useful.) If this exception is thrown, the task will not start
2457  * (which also means that the 'when' callback will not execute).
2458  * @note 1. This method will also throw if the copy or move
2459  * constructor of the callable object throws. If such an exception
2460  * is thrown, the task will not start (which also means that the
2461  * 'when' callback will not execute).
2462  * @note 2. If the callable object passed as an argument has both
2463  * const and non-const operator()() methods, the non-const version
2464  * will be called even if the callable object passed is a const
2465  * object.
2466  * @note 3. If the library is compiled using the \--with-auto-ptr
2467  * configuration option, then this method uses std::auto_ptr in place
2468  * of std::unique_ptr in its signature in order to retain
2469  * compatibility with the 1.2 series of the library.
2470  * @note 4. As mentioned in describing 'f' above, if 'f' exits by
2471  * throwing an exception the exception will be consumed and (if the
2472  * thrown object's type is not Cgu::Thread::Exit) a g_critical()
2473  * warning will be issued. The same will occur if the move
2474  * constructor (or if it has none, the copy constructor) of the
2475  * return value of 'f' throws or if the internal implementation of
2476  * this wrapper throws std::bad_alloc on executing 'f'.
2477  *
2478  * Since 2.0.13
2479  */
2480  template <class Ret, class Func>
2481 #ifdef CGU_USE_AUTO_PTR
2482  void make_task_compose(Func&& f,
2483  GMainContext* context,
2484  std::auto_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when) {
2485  make_task_when_full(when,
2486  0,
2487  std::auto_ptr<const Cgu::Callback::Callback>(),
2488  0,
2489  G_PRIORITY_DEFAULT,
2490  context,
2491  std::forward<Func>(f));
2492  }
2493 #else
2494  void make_task_compose(Func&& f,
2495  GMainContext* context,
2496  std::unique_ptr<const Cgu::Callback::CallbackArg<const Ret&>> when) {
2497  make_task_when_full(std::move(when),
2498  0,
2499  std::unique_ptr<const Cgu::Callback::Callback>(),
2500  0,
2501  G_PRIORITY_DEFAULT,
2502  context,
2503  std::forward<Func>(f));
2504  }
2505 #endif
2506 
2507  /**
2508  * If the specified minimum number of threads is greater than 0, this
2509  * constructor will start the required minimum number of threads. If
2510  * glib < 2.32 is installed, g_thread_init() must be called before
2511  * any TaskManager objects are constructed
2512  * @param max The maximum number of threads which the TaskManager
2513  * object will run in the thread pool. If the value passed as this
2514  * argument is less than the value passed as 'min', the maximum
2515  * number of threads will be set to 'min'. A value of 0 is not
2516  * valid, and if this is passed the number will be set to the greater
2517  * of 1 and 'min'.
2518  * @param min The minimum number of threads which the TaskManager
2519  * object will run in the thread pool.
2520  * @param idle The length of time in milliseconds that threads
2521  * greater in number than 'min' and not executing any tasks will
2522  * remain in existence. The default is 10000 (10 seconds).
2523  * @param blocking If true, calls to stop_all() and the destructor
2524  * will not return until the tasks remaining to be executed have
2525  * finished (what is meant by "the tasks remaining to be executed"
2526  * depends on the StopMode setting, for which see the documentation
2527  * on the stop_all() method). If false, stop_all() and the
2528  * destructor will return straight away (which in terms of the
2529  * TaskManager class implementation is safe for the reasons explained
2530  * in the documentation on the destructor).
2531  * @param mode The StopMode setting (either
2532  * Cgu::Thread::TaskManager::wait_for_running or
2533  * Cgu::Thread::TaskManager::wait_for_all) executed when running
2534  * stop_all() or when the destructor is called. See the
2535  * documentation on stop_all() for an explanation of the setting.
2536  * @exception std::bad_alloc This exception might be thrown if memory
2537  * is exhausted and the system throws in that case.
2538  * @exception Cgu::Thread::TaskError This exception will be thrown if
2539  * starting the specified minimum number of threads fails.
2540  * @exception Cgu::Thread::MutexError This exception might be thrown
2541  * if initialisation of the contained mutex fails. (It is often not
2542  * worth checking for this, as it means either memory is exhausted or
2543  * pthread has run out of other resources to create new mutexes.)
2544  * @exception Cgu::Thread::CondError This exception might be thrown
2545  * if initialisation of the contained condition variable fails. (It
2546  * is often not worth checking for this, as it means either memory is
2547  * exhausted or pthread has run out of other resources to create new
2548  * condition variables.)
2549  *
2550  * Since 2.0.12
2551  */
2552  TaskManager(unsigned int max = 8, unsigned int min = 0,
2553  unsigned int idle = 10000, bool blocking = true,
2555 
2556  /**
2557  * The destructor will call stop_all(), unless that method has
2558  * previously been called explicitly without throwing std::bad_alloc.
2559  * If the blocking setting is true, the destructor will not return
2560  * until the tasks remaining to be executed have finished (what is
2561  * meant by "the tasks remaining to be executed" depends on the
2562  * StopMode setting, for which see the documentation on the
2563  * stop_all() method.) If the blocking setting is false, the
2564  * destructor will return straight away: this is safe, because
2565  * TaskManager's internals for running tasks have been implemented
2566  * using reference counting and will not be deleted until all threads
2567  * running on the TaskManager object have finished, although the
2568  * remaining tasks should not attempt to call any of TaskManager's
2569  * methods once the TaskManager object itself has been destroyed.
2570  *
2571  * The destructor is thread safe (any thread can destroy a
2572  * TaskManager object) unless the blocking setting is true, in which
2573  * case no task running on the TaskManager object may destroy the
2574  * TaskManager object. Subject to that, it is not an error for a
2575  * thread to destroy a TaskManager object and so invoke this
2576  * destructor while another thread is already blocking in (if the
2577  * blocking setting is true) or already out of (if the blocking
2578  * setting is false) a call to stop_all() and remaining tasks are
2579  * executing: if blocking, both calls (to stop_all() and to this
2580  * destructor) would safely block together. Any given thread can
2581  * similarly safely follow a non-blocking call to stop_all() by a
2582  * non-blocking call to this destructor even though remaining tasks
2583  * are executing. However, it is an error for a thread to call
2584  * stop_all() after another thread has begun destruction of the
2585  * TaskManager object (that is, after this destructor has been
2586  * entered): there would then be an unresolvable race with the
2587  * destructor.
2588  *
2589  * The destructor will not throw.
2590  *
2591  * If stop_all() has not previously been called explicitly and throws
2592  * std::bad_alloc() when called in this destructor, the exception
2593  * will be caught and consumed, but then the destructor will not
2594  * block even if the blocking setting is true, and if the minimum
2595  * number of threads is not 0 some threads might remain running
2596  * during the entire program duration (albeit safely). Where the
2597  * throwing of std::bad_alloc is a meaningful event (usually it
2598  * isn't) and needs to be guarded against, call stop_all() explicitly
2599  * before this destructor is entered, or use a minimum thread value
2600  * of 0 and allow for the case of the destructor not blocking.
2601  *
2602  * Since 2.0.12
2603  */
2604  ~TaskManager();
2605 
2606 /* Only has effect if --with-glib-memory-slices-compat or
2607  * --with-glib-memory-slices-no-compat option picked */
2609 };
2610 
2611  /**
2612  * @class TaskManager::IncHandle task_manager.h c++-gtk-utils/task_manager.h
2613  * @brief A scoped handle for exception safe incrementing of the
2614  * maximum number of threads that a TaskManager object will run.
2615  * @sa Thread::TaskManager
2616  *
2617  * This class is for use where a task running on a TaskManager object
2618  * is about to make a blocking call. It enables the task to
2619  * increment in an exception safe way the maximum number of tasks
2620  * which the TaskManager object will currently run in its thread pool
2621  * to enable another thread to keep a core active, so that the number
2622  * is automatically decremented again when the
2623  * ThreadManager::IncHandle object has gone out of scope after the
2624  * task has finished making blocking calls or something has thrown.
2625  *
2626  * The documentation on Thread::TaskManager gives an example of its
2627  * use.
2628  *
2629  * This class is available since version 2.0.18 of the library.
2630  */
2632  TaskManager& tm;
2633 public:
2634  /**
2635  * This class cannot be copied. The copy constructor is deleted.
2636  *
2637  * Since 2.0.18
2638  */
2639  IncHandle(const TaskManager::IncHandle&) = delete;
2640 
2641  /**
2642  * This class cannot be copied. The assignment operator is deleted.
2643  *
2644  * Since 2.0.18
2645  */
2647 
2648  /**
2649  * This class requires initialisation with a TaskManager object. The
2650  * default constructor is deleted.
2651  *
2652  * Since 2.0.18
2653  */
2654  IncHandle() = delete;
2655 
2656  /**
2657  * This constructor calls TaskManager::change_max_threads() to
2658  * increment the maximum number of threads a TaskManager object will
2659  * currently run in its thread pool.
2660  * @param tm_ The TaskManager object whose maximum thread limit is to
2661  * be incremented.
2662  * @exception std::bad_alloc If tasks are currently queued for
2663  * execution, a new thread will be started, so this exception may be
2664  * thrown on starting the thread if memory is exhausted and the
2665  * system throws in that case. (On systems with
2666  * over-commit/lazy-commit combined with virtual memory (swap), it is
2667  * rarely useful to check for memory exhaustion).
2668  * @exception Cgu::Thread::TaskError If tasks are currently queued
2669  * for execution, a new thread will be started, so this exception may
2670  * be thrown on starting the thread if it fails to start correctly
2671  * (this would mean that memory is exhausted, the pthread thread
2672  * limit has been reached or pthread has run out of other resources
2673  * to start new threads).
2674  *
2675  * Since 2.0.18
2676  */
2677  explicit IncHandle(TaskManager& tm_): tm(tm_) {
2678  tm_.change_max_threads(1);
2679  }
2680 
2681  /**
2682  * This destructor calls TaskManager::change_max_threads() to
2683  * decrement the maximum number of threads a TaskManager object will
2684  * currently run in its thread pool. It will not throw.
2685  *
2686  * Since 2.0.18
2687  */
2689 };
2690 
2691 } // namespace Thread
2692 
2693 } // namespace Cgu
2694 
2695 #include <c++-gtk-utils/task_manager.tpp>
2696 
2697 #endif
unsigned int get_min_threads() const
StopMode
Definition: task_manager.h:462
unsigned int get_tasks() const
void add_task(const Callback::Callback *task)
Definition: task_manager.h:842
void make_task_compose(Func &&f, GMainContext *context, std::unique_ptr< const Cgu::Callback::CallbackArg< const Ret & >> when)
Definition: task_manager.h:2494
A thread-pool class for managing tasks in multi-threaded programs.
Definition: task_manager.h:460
CallbackArg< FreeArgs...> * make_ref(T &t, void(T::*func)(FreeArgs...))
Definition: callback.h:1701
Definition: task_manager.h:61
virtual const char * what() const
Definition: task_manager.h:62
void make_task_when(std::unique_ptr< const Cgu::Callback::CallbackArg< const Ret & >> when, GMainContext *context, const T &t, Ret(T::*func)(Params...) const, Args &&...args)
Definition: task_manager.h:1623
This file provides thread-safe asynchronous queue classes.
static void exec(FType &f, const SharedLockPtr< AsyncResult< Ret >> &ret)
Definition: task_manager.h:419
void make_task_when(std::unique_ptr< const Cgu::Callback::CallbackArg< const Ret & >> when, GMainContext *context, Ret(*func)(Params...), Args &&...args)
Definition: task_manager.h:1955
void dispatch() const
Definition: task_manager.h:448
This is a smart pointer for managing the lifetime of objects allocated on freestore, with a thread safe reference count.
Definition: shared_ptr.h:644
static void do_fail(const SharedLockPtr< AsyncResult< Ret >> &ret)
Definition: task_manager.h:423
void set_max_threads(unsigned int max)
Cgu::SharedLockPtr< Cgu::AsyncResult< Ret > > make_task_result(T &t, Ret(T::*func)(Params...), Args &&...args)
void set_blocking(bool blocking)
STL namespace.
unsigned int get_idle_time() const
A scoped handle for exception safe incrementing of the maximum number of threads that a TaskManager o...
Definition: task_manager.h:2631
void make_task_when(std::unique_ptr< const Cgu::Callback::CallbackArg< const Ret & >> when, GMainContext *context, Func &&f)
Definition: task_manager.h:2369
This file provides classes for type erasure.
TaskManager & operator=(const TaskManager &)=delete
FunctorResultExec(FunctorArg &&functor_, const SharedLockPtr< AsyncResult< Ret >> &ret_)
Definition: task_manager.h:452
void make_task_when_full(std::unique_ptr< const Cgu::Callback::CallbackArg< const Ret & >> when, Cgu::Releaser *when_releaser, std::unique_ptr< const Cgu::Callback::Callback > fail, Cgu::Releaser *fail_releaser, gint priority, GMainContext *context, T &t, Ret(T::*func)(Params...), Args &&...args)
void make_task_when(std::unique_ptr< const Cgu::Callback::CallbackArg< const Ret & >> when, GMainContext *context, T &t, Ret(T::*func)(Params...), Args &&...args)
Definition: task_manager.h:1277
static unsigned int get_max_tasks()
Definition: task_manager.h:651
A thread-safe asynchronous result class.
Definition: async_result.h:165
IncHandle(TaskManager &tm_)
Definition: task_manager.h:2677
void set_stop_mode(StopMode mode)
unsigned int get_max_threads() const
unsigned int get_used_threads() const
This file provides a thread-safe signal/slot mechanism, with automatic disconnection.
Provides wrapper classes for pthread mutexes and condition variables, and scoped locking classes for ...
Definition: application.h:44
StopMode get_stop_mode() const
A scoped locking class for exception safe Mutex locking which tracks the status of its mutex...
Definition: mutex.h:331
This file provides a thread-safe asynchronous result class.
Definition: task_manager.h:462
void change_max_threads(int delta)
void set_idle_time(unsigned int idle)
~IncHandle()
Definition: task_manager.h:2688
TaskManager(const TaskManager &)=delete
Definition: task_manager.h:462
bool get_blocking() const
The callback interface class.
Definition: callback.h:522
#define CGU_GLIB_MEMORY_SLICES_FUNCS
Definition: cgu_config.h:84
A class used for tracking EmitterArg and SafeEmitterArg connections.
Definition: emitter.h:333