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