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