c++-gtk-utils: timeout.h Source File

c++-gtk-utils

- Main Page
- Related Pages
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

timeout.h
Go to the documentation of this file.
1 /* Copyright (C) 2009 and 2014 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 */
24
25 #ifndef CGU_TIMEOUT_H
26 #define CGU_TIMEOUT_H
27
28 /**
29 * @defgroup timeout timeout
30 *
31 * \#include <c++-gtk-utils/timeout.h>
32 *
33 * The start_timeout() function connects a timeout to an event loop
34 * owned by a GMainContext object (normally the main program loop).
35 * By so doing, it provides a convenient way of attaching the callback
36 * for the timeout, and also provides for automatic disconnection when
37 * an object whose function the callback represents is destroyed. The
38 * timeout will keep executing the callback at the intervals set in
39 * start_timeout() until it is terminated in one of the ways mentioned
40 * below.
41 *
42 * The simplest way to use the start_timeout() function is to pass it
43 * a callable object, such as a lambda expression or the return value
44 * of std::bind. The callable object should take a single unbound
45 * bool& argument. If it is set by the callable object to false, then
46 * the timeout calls will be ended and all resources connected with it
47 * deleted without further user action being required (there is no
48 * need for the connected function to set it to true if timeout
49 * execution is to continue, as that is the default).
50 *
51 * Other overloads of start_iowatch() take the more explicitly typed
52 * Callback::CallbackArg<bool&> callback object (as constructed with
53 * Callback::lambda(), Callback::make() or Callback::make_ref()).
54 *
55 * All of the start_iowatch() overloads have an option to take a
56 * Callback::Releaser object as their third argument, which provides
57 * for automatic termination of the execution of the callback at the
58 * specified interval if the target object which has the Releaser as a
59 * member is destroyed. (Note that for this to be race free, the
60 * lifetime of the remote target object whose method is to be invoked
61 * must be determined by the thread to whose main loop the timeout has
62 * been attached. When the main loop begins invoking the execution of
63 * the timeout callback, the remote object must either wholly exist,
64 * in which case the callback will be invoked, or have been destroyed,
65 * in which case the callback will be ignored, and not be in some
66 * transient half-state governed by another thread.)
67 *
68 * start_timeout() is thread-safe (it may be called in any thread)
69 * provided that, if glib < 2.32 is used, the glib main loop has been
70 * made thread-safe by a call to g_thread_init(). glib >= 2.32 does
71 * not require g_thread_init() to be called in order to be
72 * thread-safe.
73 *
74 * As mentioned above, the connected callback passed to
75 * start_timeout() has an unbound bool& argument. The timeout calls
76 * will be ended if that argument is set by the connected callback to
77 * false. In addition, the timeout will be ended automatically and
78 * resources deleted if (i) as mentioned above, the callback passed to
79 * start_timeout() is protected by a Releaser object and the target
80 * object having the Releaser as a member is destroyed, or (ii)
81 * g_source_remove() is called on the source id returned by
82 * start_timeout() (where the timeout is attached to the default main
83 * context) or g_source_destroy() is called on the GSource object
84 * obtained from that id with g_main_context_find_source_by_id()
85 * (where the timeout has been attached to a non-default main
86 * context). If the source has been removed automatically by virtue
87 * of the bool& argument being set to false or by virtue of a Releaser
88 * object releasing, g_source_remove() or g_source_destroy() should
89 * not afterwards be called in respect of the id value returned by
90 * start_timeout() in case it has been reused by the main context
91 * concerned in the meantime.
92 *
93 * The start_timeout_seconds() functions do the same as their
94 * start_timeout() counterparts, except that they use the larger
95 * granularity glib timeout-seconds main loop event sources (and take
96 * seconds and not milliseconds as their timeout argument). The idea
97 * behind the glib timeout-seconds sources is to group long timeout
98 * events which do not have critical timing resolution requirements so
99 * that they are aligned together with one second granularity. This
100 * minimises the number of processor wake-ups required to handle such
101 * events, thereby helping power efficiency. These functions are to
102 * be preferred for long timeouts where one second granularity is
103 * acceptable. These larger granularity functions are only compiled
104 * into the library if glib >= 2.14 is installed.
105 */
106
107 #include <glib.h>
108 #include <c++-gtk-utils/callback.h>
109 #include <c++-gtk-utils/cgu_config.h>
110
111 namespace Cgu {
112
113 class Releaser;
114
115 /**
116 * Starts a timeout in the glib main loop, and executes the callback
117 * when the timeout expires. It is thread-safe (it may be called in
118 * any thread) provided that, if glib < 2.32 is used, g_thread_init()
119 * has been called. glib >= 2.32 does not require g_thread_init() to
120 * be called to be thread-safe. This function will not throw.
121 * @param millisec The interval of the timeout, in milliseconds.
122 * @param cb The callback object. Ownership is taken of this object,
123 * and it will be deleted when it has been finished with.
124 * @param priority The priority to be given to the timeout in the
125 * main loop. In ascending order of priorities, priorities are
126 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
127 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
128 * G_PRIORITY_DEFAULT. This determines the order in which the
129 * callback will appear in the event list in the main loop, not the
130 * priority which the OS will adopt
131 * @param context The glib main context to which the timeout is to be
132 * attached (the default of NULL will cause the timeout to be attached
133 * to the main program loop, and this is almost always what is
134 * wanted).
135 * @return The glib source id of the timeout.
136 * @note 1. Cancellation of the thread to which the timeout is
137 * attached is blocked during execution of the callback.
138 * @note 2. If the callback throws an exception, the exception will be
139 * consumed to protect the main loop and a g_critical() warning will
140 * be issued.
141 * @ingroup timeout
142 */
143 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
144 gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
145
146 /**
147 * Starts a timeout in the glib main loop, and executes the callback
148 * when the timeout expires. This version provides for automatic
149 * timeout disconnection when the object whose function the callback
150 * represents is destroyed, via the Releaser object. It is
151 * thread-safe (it may be called in any thread) provided that, if glib
152 * < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does
153 * not require g_thread_init() to be called to be thread-safe.
154 * @param millisec The interval of the timeout, in milliseconds.
155 * @param cb The callback object. Ownership is taken of this object,
156 * and it will be deleted when it has been finished with.
157 * @param r A Releaser object which the protected object has as a
158 * public member.
159 * @param priority The priority to be given to the timeout in the
160 * main loop. In ascending order of priorities, priorities are
161 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
162 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
163 * G_PRIORITY_DEFAULT. This determines the order in which the
164 * callback will appear in the event list in the main loop, not the
165 * priority which the OS will adopt
166 * @param context The glib main context to which the timeout is to be
167 * attached (the default of NULL will cause the timeout to be attached
168 * to the main program loop, and this is almost always what is
169 * wanted).
170 * @return The glib source id of the timeout.
171 * @exception std::bad_alloc This function might throw std::bad_alloc
172 * if memory is exhausted and the system throws in that case. If it
173 * does so, the CallbackArg object will be disposed of.
174 * @exception Cgu::Thread::MutexError This function might throw
175 * Cgu:Thread::MutexError if initialisation of the mutex in a
176 * SafeEmitterArg object constructed by this function fails. If it
177 * does so, the CallbackArg object will be disposed of. (It is often
178 * not worth checking for this exception, as it means either memory is
179 * exhausted or pthread has run out of other resources to create new
180 * mutexes.)
181 * @note 1. Cancellation of the thread to which the timeout is
182 * attached is blocked during execution of the callback.
183 * @note 2. If the callback throws an exception, the exception will be
184 * consumed to protect the main loop and a g_critical() warning will
185 * be issued.
186 * @note 3. By virtue of the Releaser object, it is in theory possible
187 * (if memory is exhausted and the system throws in that case) that an
188 * internal SafeEmitterArg object will throw std::bad_alloc when
189 * emitting/executing the timeout callback in the glib main loop, with
190 * the result that the relevant callback will not execute (instead the
191 * exception will be consumed and a g_critical() warning will be
192 * issued) and thus will be delayed until expiry of the next timeout
193 * interval. This is rarely of any relevance because glib will abort
194 * the program if it is itself unable to obtain memory from the
195 * operating system. However, where it is relevant, design the
196 * program so that it is not necessary to provide a releaser object.
197 * @ingroup timeout
198 */
199 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
200 Releaser& r, gint priority = G_PRIORITY_DEFAULT,
201 GMainContext* context = 0);
202
203 /**
204 * Starts a timeout in the glib main loop, and executes a callable
205 * object when the timeout expires. It is thread-safe (it may be
206 * called in any thread) provided that, if glib < 2.32 is used,
207 * g_thread_init() has been called. glib >= 2.32 does not require
208 * g_thread_init() to be called to be thread-safe.
209 * @param millisec The interval of the timeout, in milliseconds.
210 * @param func A callable object, such as formed by a lambda
211 * expression or the result of std::bind. It should take an unbound
212 * bool& argument.
213 * @param priority The priority to be given to the timeout in the
214 * main loop. In ascending order of priorities, priorities are
215 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
216 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
217 * G_PRIORITY_DEFAULT. This determines the order in which the
218 * callback will appear in the event list in the main loop, not the
219 * priority which the OS will adopt
220 * @param context The glib main context to which the timeout is to be
221 * attached (the default of NULL will cause the timeout to be attached
222 * to the main program loop, and this is almost always what is
223 * wanted).
224 * @return The glib source id of the timeout.
225 * @exception std::bad_alloc This function might throw std::bad_alloc
226 * if memory is exhausted and the system throws in that case (this
227 * exception will not be thrown if the library has been installed
228 * using the \--with-glib-memory-slices-no-compat configuration
229 * option: instead glib will terminate the program if it is unable to
230 * obtain memory from the operating system).
231 * @note 1. This function may also throw if the copy or move
232 * constructor of the callable object throws.
233 * @note 2. Cancellation of the thread to which the timeout is
234 * attached is blocked during execution of the callback.
235 * @note 3. If the callback throws an exception, the exception will be
236 * consumed to protect the main loop and a g_critical() warning will
237 * be issued.
238 * @ingroup timeout
239 *
240 * Since 2.1.0
241 */
242 template <class F,
243 class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type,
244 const Callback::CallbackArg<bool&>*>::value>::type>
245 // we need to use enable_if so that where this function is passed a
246 // pointer to non-const Callback::CallbackArg, or some other
247 // convertible pointer, this templated overload is dropped from the
248 // overload set, in order to support the Callback::CallbackArg pointer
249 // overloads of this function. This overload calls into the version
250 // of this function taking a pointer to const Callback::CallbackArg in
251 // order to perform type erasure.
252 guint start_timeout(guint millisec, F&& func,
253 gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0) {
254 return start_timeout(millisec, Callback::lambda<bool&>(std::forward<F>(func)),
255 priority, context);
256 }
257
258 /**
259 * Starts a timeout in the glib main loop, and executes a callable
260 * object when the timeout expires. This version provides for
261 * automatic timeout disconnection when an object whose function the
262 * callback represents or calls into is destroyed, via the Releaser
263 * object. It is thread-safe (it may be called in any thread)
264 * provided that, if glib < 2.32 is used, g_thread_init() has been
265 * called. glib >= 2.32 does not require g_thread_init() to be called
266 * to be thread-safe.
267 * @param millisec The interval of the timeout, in milliseconds.
268 * @param func A callable object, such as formed by a lambda
269 * expression or the result of std::bind. It should take an unbound
270 * bool& argument.
271 * @param r A Releaser object which the protected object has as a
272 * public member.
273 * @param priority The priority to be given to the timeout in the
274 * main loop. In ascending order of priorities, priorities are
275 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
276 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
277 * G_PRIORITY_DEFAULT. This determines the order in which the
278 * callback will appear in the event list in the main loop, not the
279 * priority which the OS will adopt
280 * @param context The glib main context to which the timeout is to be
281 * attached (the default of NULL will cause the timeout to be attached
282 * to the main program loop, and this is almost always what is
283 * wanted).
284 * @return The glib source id of the timeout.
285 * @exception std::bad_alloc This function might throw std::bad_alloc
286 * if memory is exhausted and the system throws in that case.
287 * @exception Cgu::Thread::MutexError This function might throw
288 * Cgu:Thread::MutexError if initialisation of the mutex in a
289 * SafeEmitterArg object constructed by this function fails. (It is
290 * often not worth checking for this exception, as it means either
291 * memory is exhausted or pthread has run out of other resources to
292 * create new mutexes.)
293 * @note 1. This function may also throw if the copy or move
294 * constructor of the callable object throws.
295 * @note 2. Cancellation of the thread to which the timeout is
296 * attached is blocked during execution of the callback.
297 * @note 3. If the callback throws an exception, the exception will be
298 * consumed to protect the main loop and a g_critical() warning will
299 * be issued.
300 * @note 4. By virtue of the Releaser object, it is in theory possible
301 * (if memory is exhausted and the system throws in that case) that an
302 * internal SafeEmitterArg object will throw std::bad_alloc when
303 * emitting/executing the timeout callback in the glib main loop, with
304 * the result that the relevant callback will not execute (instead the
305 * exception will be consumed and a g_critical() warning will be
306 * issued) and thus will be delayed until expiry of the next timeout
307 * interval. This is rarely of any relevance because glib will abort
308 * the program if it is itself unable to obtain memory from the
309 * operating system. However, where it is relevant, design the
310 * program so that it is not necessary to provide a releaser object.
311 * @ingroup timeout
312 *
313 * Since 2.1.0
314 */
315 // we need to use enable_if so that where this function is passed a
316 // pointer to non-const Callback::CallbackArg, or some other
317 // convertible pointer, this templated overload is dropped from the
318 // overload set, in order to support the Callback::CallbackArg pointer
319 // overloads of this function. This overload calls into the version
320 // of this function taking a pointer to const Callback::CallbackArg in
321 // order to perform type erasure.
322 template <class F,
323 class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type,
324 const Callback::CallbackArg<bool&>*>::value>::type>
325 guint start_timeout(guint millisec, F&& func,
326 Releaser& r, gint priority = G_PRIORITY_DEFAULT,
327 GMainContext* context = 0) {
328 return start_timeout(millisec, Callback::lambda<bool&>(std::forward<F>(func)),
329 r, priority,
330 context);
331 }
332
333 /**
334 * Starts a timeout in the glib main loop using the higher granularity
335 * glib timeout-seconds event sources, and executes the callback when
336 * the timeout expires. It is thread-safe (it may be called in any
337 * thread) provided that, if glib < 2.32 is used, g_thread_init() has
338 * been called. glib >= 2.32 does not require g_thread_init() to be
339 * called to be thread-safe. This function will not throw.
340 * @param sec The interval of the timeout, in seconds.
341 * @param cb The callback object. Ownership is taken of this object,
342 * and it will be deleted when it has been finished with.
343 * @param priority The priority to be given to the timeout in the
344 * main loop. In ascending order of priorities, priorities are
345 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
346 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
347 * G_PRIORITY_DEFAULT. This determines the order in which the
348 * callback will appear in the event list in the main loop, not the
349 * priority which the OS will adopt
350 * @param context The glib main context to which the timeout is to be
351 * attached (the default of NULL will cause the timeout to be attached
352 * to the main program loop, and this is almost always what is
353 * wanted).
354 * @return The glib source id of the timeout.
355 * @note 1. Cancellation of the thread to which the timeout is
356 * attached is blocked during execution of the callback.
357 * @note 2. If the callback throws an exception, the exception will be
358 * consumed to protect the main loop and a g_critical() warning will
359 * be issued.
360 * @note 3. This function is only compiled into the library if glib >=
361 * 2.14 is installed.
362 * @ingroup timeout
363 */
364 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
365 gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
366
367 /**
368 * Starts a timeout in the glib main loop using the higher granularity
369 * glib timeout-seconds event sources, and executes the callback when
370 * the timeout expires. This version provides for automatic timeout
371 * disconnection when the object whose function the callback
372 * represents is destroyed, via the Releaser object. It is
373 * thread-safe (it may be called in any thread) provided that, if glib
374 * < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does
375 * not require g_thread_init() to be called to be thread-safe.
376 * @param sec The interval of the timeout, in seconds.
377 * @param cb The callback object. Ownership is taken of this object,
378 * and it will be deleted when it has been finished with.
379 * @param r A Releaser object which the protected object has as a
380 * public member.
381 * @param priority The priority to be given to the timeout in the
382 * main loop. In ascending order of priorities, priorities are
383 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
384 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
385 * G_PRIORITY_DEFAULT. This determines the order in which the
386 * callback will appear in the event list in the main loop, not the
387 * priority which the OS will adopt
388 * @param context The glib main context to which the timeout is to be
389 * attached (the default of NULL will cause the timeout to be attached
390 * to the main program loop, and this is almost always what is
391 * wanted).
392 * @return The glib source id of the timeout.
393 * @exception std::bad_alloc This function might throw std::bad_alloc
394 * if memory is exhausted and the system throws in that case. If it
395 * does so, the CallbackArg object will be disposed of.
396 * @exception Cgu::Thread::MutexError This function might throw
397 * Cgu:Thread::MutexError if initialisation of the mutex in a
398 * SafeEmitterArg object constructed by this function fails. If it
399 * does so, the CallbackArg object will be disposed of. (It is often
400 * not worth checking for this exception, as it means either memory is
401 * exhausted or pthread has run out of other resources to create new
402 * mutexes.)
403 * @note 1. Cancellation of the thread to which the timeout is
404 * attached is blocked during execution of the callback.
405 * @note 2. If the callback throws an exception, the exception will be
406 * consumed to protect the main loop and a g_critical() warning will
407 * be issued.
408 * @note 3. This function is only compiled into the library if glib >=
409 * 2.14 is installed.
410 * @note 4. By virtue of the Releaser object, it is in theory possible
411 * (if memory is exhausted and the system throws in that case) that an
412 * internal SafeEmitterArg object will throw std::bad_alloc when
413 * emitting/executing the timeout callback in the glib main loop, with
414 * the result that the relevant callback will not execute (instead the
415 * exception will be consumed and a g_critical() warning will be
416 * issued) and thus will be delayed until expiry of the next timeout
417 * interval. This is rarely of any relevance because glib will abort
418 * the program if it is itself unable to obtain memory from the
419 * operating system. However, where it is relevant, design the
420 * program so that it is not necessary to provide a releaser object.
421 * @ingroup timeout
422 */
423 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
424 Releaser& r, gint priority = G_PRIORITY_DEFAULT,
425 GMainContext* context = 0);
426
427 /**
428 * Starts a timeout in the glib main loop using the higher granularity
429 * glib timeout-seconds event sources, and executes a callable object
430 * when the timeout expires. It is thread-safe (it may be called in
431 * any thread) provided that, if glib < 2.32 is used, g_thread_init()
432 * has been called. glib >= 2.32 does not require g_thread_init() to
433 * be called to be thread-safe.
434 * @param sec The interval of the timeout, in seconds.
435 * @param func A callable object, such as formed by a lambda
436 * expression or the result of std::bind. It should take an unbound
437 * bool& argument.
438 * @param priority The priority to be given to the timeout in the
439 * main loop. In ascending order of priorities, priorities are
440 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
441 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
442 * G_PRIORITY_DEFAULT. This determines the order in which the
443 * callback will appear in the event list in the main loop, not the
444 * priority which the OS will adopt
445 * @param context The glib main context to which the timeout is to be
446 * attached (the default of NULL will cause the timeout to be attached
447 * to the main program loop, and this is almost always what is
448 * wanted).
449 * @return The glib source id of the timeout.
450 * @exception std::bad_alloc This function might throw std::bad_alloc
451 * if memory is exhausted and the system throws in that case (this
452 * exception will not be thrown if the library has been installed
453 * using the \--with-glib-memory-slices-no-compat configuration
454 * option: instead glib will terminate the program if it is unable to
455 * obtain memory from the operating system).
456 * @note 1. This function may also throw if the copy or move
457 * constructor of the callable object throws.
458 * @note 2. Cancellation of the thread to which the timeout is
459 * attached is blocked during execution of the callback.
460 * @note 3. If the callback throws an exception, the exception will be
461 * consumed to protect the main loop and a g_critical() warning will
462 * be issued.
463 * @note 4. This function is only compiled into the library if glib >=
464 * 2.14 is installed.
465 * @ingroup timeout
466 *
467 * Since 2.1.0
468 */
469 template <class F,
470 class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type,
471 const Callback::CallbackArg<bool&>*>::value>::type>
472 // we need to use enable_if so that where this function is passed a
473 // pointer to non-const Callback::CallbackArg, or some other
474 // convertible pointer, this templated overload is dropped from the
475 // overload set, in order to support the Callback::CallbackArg pointer
476 // overloads of this function. This overload calls into the version
477 // of this function taking a pointer to const Callback::CallbackArg in
478 // order to perform type erasure.
479 guint start_timeout_seconds(guint sec, F&& func,
480 gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0) {
481 return start_timeout_seconds(sec, Callback::lambda<bool&>(std::forward<F>(func)),
482 priority, context);
483 }
484
485 /**
486 * Starts a timeout in the glib main loop using the higher granularity
487 * glib timeout-seconds event sources, and executes a callback object
488 * when the timeout expires. This version provides for automatic
489 * timeout disconnection when an object whose function the callback
490 * represents or calls into is destroyed, via the Releaser object. It
491 * is thread-safe (it may be called in any thread) provided that, if
492 * glib < 2.32 is used, g_thread_init() has been called. glib >= 2.32
493 * does not require g_thread_init() to be called to be thread-safe.
494 * @param sec The interval of the timeout, in seconds.
495 * @param func A callable object, such as formed by a lambda
496 * expression or the result of std::bind. It should take an unbound
497 * bool& argument.
498 * @param r A Releaser object which the protected object has as a
499 * public member.
500 * @param priority The priority to be given to the timeout in the
501 * main loop. In ascending order of priorities, priorities are
502 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
503 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
504 * G_PRIORITY_DEFAULT. This determines the order in which the
505 * callback will appear in the event list in the main loop, not the
506 * priority which the OS will adopt
507 * @param context The glib main context to which the timeout is to be
508 * attached (the default of NULL will cause the timeout to be attached
509 * to the main program loop, and this is almost always what is
510 * wanted).
511 * @return The glib source id of the timeout.
512 * @exception std::bad_alloc This function might throw std::bad_alloc
513 * if memory is exhausted and the system throws in that case.
514 * @exception Cgu::Thread::MutexError This function might throw
515 * Cgu:Thread::MutexError if initialisation of the mutex in a
516 * SafeEmitterArg object constructed by this function fails. (It is
517 * often not worth checking for this exception, as it means either
518 * memory is exhausted or pthread has run out of other resources to
519 * create new mutexes.)
520 * @note 1. This function may also throw if the copy or move
521 * constructor of the callable object throws.
522 * @note 2. Cancellation of the thread to which the timeout is
523 * attached is blocked during execution of the callback.
524 * @note 3. If the callback throws an exception, the exception will be
525 * consumed to protect the main loop and a g_critical() warning will
526 * be issued.
527 * @note 4. This function is only compiled into the library if glib >=
528 * 2.14 is installed.
529 * @note 5. By virtue of the Releaser object, it is in theory possible
530 * (if memory is exhausted and the system throws in that case) that an
531 * internal SafeEmitterArg object will throw std::bad_alloc when
532 * emitting/executing the timeout callback in the glib main loop, with
533 * the result that the relevant callback will not execute (instead the
534 * exception will be consumed and a g_critical() warning will be
535 * issued) and thus will be delayed until expiry of the next timeout
536 * interval. This is rarely of any relevance because glib will abort
537 * the program if it is itself unable to obtain memory from the
538 * operating system. However, where it is relevant, design the
539 * program so that it is not necessary to provide a releaser object.
540 * @ingroup timeout
541 *
542 * Since 2.1.0
543 */
544 // we need to use enable_if so that where this function is passed a
545 // pointer to non-const Callback::CallbackArg, or some other
546 // convertible pointer, this templated overload is dropped from the
547 // overload set, in order to support the Callback::CallbackArg pointer
548 // overloads of this function. This overload calls into the version
549 // of this function taking a pointer to const Callback::CallbackArg in
550 // order to perform type erasure.
551 template <class F,
552 class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type,
553 const Callback::CallbackArg<bool&>*>::value>::type>
554 guint start_timeout_seconds(guint sec, F&& func,
555 Releaser& r, gint priority = G_PRIORITY_DEFAULT,
556 GMainContext* context = 0) {
557 return start_timeout_seconds(sec, Callback::lambda<bool&>(std::forward<F>(func)),
558 r, priority,
559 context);
560 }
561
562 } // namespace Cgu
563
564 #endif