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 2013 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 Cancellation of the thread to which the timeout is attached is
137 * blocked during execution of the callback.
138 * @ingroup timeout
139 */
140 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
141 gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
142
143 /**
144 * Starts a timeout in the glib main loop, and executes the callback
145 * when the timeout expires. This version provides for automatic
146 * timeout disconnection when the object whose function the callback
147 * represents is destroyed, via the Releaser object. It is
148 * thread-safe (it may be called in any thread) provided that, if glib
149 * < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does
150 * not require g_thread_init() to be called to be thread-safe.
151 * @param millisec The interval of the timeout, in milliseconds.
152 * @param cb The callback object. Ownership is taken of this object,
153 * and it will be deleted when it has been finished with.
154 * @param r A Releaser object which the protected object has as a
155 * public member.
156 * @param priority The priority to be given to the timeout in the
157 * main loop. In ascending order of priorities, priorities are
158 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
159 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
160 * G_PRIORITY_DEFAULT. This determines the order in which the
161 * callback will appear in the event list in the main loop, not the
162 * priority which the OS will adopt
163 * @param context The glib main context to which the timeout is to be
164 * attached (the default of NULL will cause the timeout to be attached
165 * to the main program loop, and this is almost always what is
166 * wanted).
167 * @return The glib source id of the timeout.
168 * @exception std::bad_alloc This function might throw std::bad_alloc
169 * if memory is exhausted and the system throws in that case. If it
170 * does so, the CallbackArg object will be disposed of.
171 * @exception Cgu::Thread::MutexError This method might throw
172 * Cgu:Thread::MutexError if initialisation of the mutex in a
173 * SafeEmitterArg object constructed by this method fails. If it does
174 * so, the CallbackArg object will be disposed of. (It is often not
175 * worth checking for this exception, as it means either memory is
176 * exhausted or pthread has run out of other resources to create new
177 * mutexes.)
178 * @note 1. Cancellation of the thread to which the timeout is
179 * attached is blocked during execution of the callback.
180 * @note 2. By virtue of the Releaser object, it is in theory possible
181 * (if memory is exhausted and the system throws in that case) that an
182 * internal SafeEmitterArg object will throw std::bad_alloc when
183 * emitting/executing the timeout callback in the glib main loop, with
184 * the result that the relevant callback will not execute (instead the
185 * exception will be consumed and a g_critical() warning will be
186 * issued) and thus will be delayed until expiry of the next timeout
187 * interval. This is rarely of any relevance because glib will abort
188 * the program if it is itself unable to obtain memory from the
189 * operating system. However, where it is relevant, design the
190 * program so that it is not necessary to provide a releaser object.
191 * @ingroup timeout
192 */
193 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
194 Releaser& r, gint priority = G_PRIORITY_DEFAULT,
195 GMainContext* context = 0);
196
197 /**
198 * Starts a timeout in the glib main loop, and executes a callable
199 * object when the timeout expires. It is thread-safe (it may be
200 * called in any thread) provided that, if glib < 2.32 is used,
201 * g_thread_init() has been called. glib >= 2.32 does not require
202 * g_thread_init() to be called to be thread-safe. This function will
203 * not throw unless the copy or move constructor of the callable
204 * object throws.
205 * @param millisec The interval of the timeout, in milliseconds.
206 * @param func A callable object, such as formed by a lambda
207 * expression or the result of std::bind. It should take an unbound
208 * bool& argument.
209 * @param priority The priority to be given to the timeout in the
210 * main loop. In ascending order of priorities, priorities are
211 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
212 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
213 * G_PRIORITY_DEFAULT. This determines the order in which the
214 * callback will appear in the event list in the main loop, not the
215 * priority which the OS will adopt
216 * @param context The glib main context to which the timeout is to be
217 * attached (the default of NULL will cause the timeout to be attached
218 * to the main program loop, and this is almost always what is
219 * wanted).
220 * @return The glib source id of the timeout.
221 * @note Cancellation of the thread to which the timeout is attached is
222 * blocked during execution of the callback.
223 * @ingroup timeout
224 *
225 * Since 2.1.0
226 */
227 template <class F,
228 class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type,
229 const Callback::CallbackArg<bool&>*>::value>::type>
230 // we need to use enable_if so that where this function is passed a
231 // pointer to non-const Callback::CallbackArg, or some other
232 // convertible pointer, this templated overload is dropped from the
233 // overload set, in order to support the Callback::CallbackArg pointer
234 // overloads of this function. This overload calls into the version
235 // of this function taking a pointer to const Callback::CallbackArg in
236 // order to perform type erasure.
237 guint start_timeout(guint millisec, F&& func,
238 gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0) {
239 return start_timeout(millisec, Callback::lambda<bool&>(std::forward<F>(func)),
240 priority, context);
241 }
242
243 /**
244 * Starts a timeout in the glib main loop, and executes a callable
245 * object when the timeout expires. This version provides for
246 * automatic timeout disconnection when an object whose function the
247 * callback represents or calls into is destroyed, via the Releaser
248 * object. It is thread-safe (it may be called in any thread)
249 * provided that, if glib < 2.32 is used, g_thread_init() has been
250 * called. glib >= 2.32 does not require g_thread_init() to be called
251 * to be thread-safe.
252 * @param millisec The interval of the timeout, in milliseconds.
253 * @param func A callable object, such as formed by a lambda
254 * expression or the result of std::bind. It should take an unbound
255 * bool& argument.
256 * @param r A Releaser object which the protected object has as a
257 * public member.
258 * @param priority The priority to be given to the timeout in the
259 * main loop. In ascending order of priorities, priorities are
260 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
261 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
262 * G_PRIORITY_DEFAULT. This determines the order in which the
263 * callback will appear in the event list in the main loop, not the
264 * priority which the OS will adopt
265 * @param context The glib main context to which the timeout is to be
266 * attached (the default of NULL will cause the timeout to be attached
267 * to the main program loop, and this is almost always what is
268 * wanted).
269 * @return The glib source id of the timeout.
270 * @exception std::bad_alloc This function might throw std::bad_alloc
271 * if memory is exhausted and the system throws in that case.
272 * @exception Cgu::Thread::MutexError This method might throw
273 * Cgu:Thread::MutexError if initialisation of the mutex in a
274 * SafeEmitterArg object constructed by this method fails. (It is
275 * often not worth checking for this exception, as it means either
276 * memory is exhausted or pthread has run out of other resources to
277 * create new mutexes.)
278 * @note 1. This function may also throw if the copy or move
279 * constructor of the callable object throws.
280 * @note 2. Cancellation of the thread to which the timeout is
281 * attached is blocked during execution of the callback.
282 * @note 3. By virtue of the Releaser object, it is in theory possible
283 * (if memory is exhausted and the system throws in that case) that an
284 * internal SafeEmitterArg object will throw std::bad_alloc when
285 * emitting/executing the timeout callback in the glib main loop, with
286 * the result that the relevant callback will not execute (instead the
287 * exception will be consumed and a g_critical() warning will be
288 * issued) and thus will be delayed until expiry of the next timeout
289 * interval. This is rarely of any relevance because glib will abort
290 * the program if it is itself unable to obtain memory from the
291 * operating system. However, where it is relevant, design the
292 * program so that it is not necessary to provide a releaser object.
293 * @ingroup timeout
294 *
295 * Since 2.1.0
296 */
297 // we need to use enable_if so that where this function is passed a
298 // pointer to non-const Callback::CallbackArg, or some other
299 // convertible pointer, this templated overload is dropped from the
300 // overload set, in order to support the Callback::CallbackArg pointer
301 // overloads of this function. This overload calls into the version
302 // of this function taking a pointer to const Callback::CallbackArg in
303 // order to perform type erasure.
304 template <class F,
305 class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type,
306 const Callback::CallbackArg<bool&>*>::value>::type>
307 guint start_timeout(guint millisec, F&& func,
308 Releaser& r, gint priority = G_PRIORITY_DEFAULT,
309 GMainContext* context = 0) {
310 return start_timeout(millisec, Callback::lambda<bool&>(std::forward<F>(func)),
311 r, priority,
312 context);
313 }
314
315 /**
316 * Starts a timeout in the glib main loop using the higher granularity
317 * glib timeout-seconds event sources, and executes the callback when
318 * the timeout expires. It is thread-safe (it may be called in any
319 * thread) provided that, if glib < 2.32 is used, g_thread_init() has
320 * been called. glib >= 2.32 does not require g_thread_init() to be
321 * called to be thread-safe. This function will not throw.
322 * @param sec The interval of the timeout, in seconds.
323 * @param cb The callback object. Ownership is taken of this object,
324 * and it will be deleted when it has been finished with.
325 * @param priority The priority to be given to the timeout in the
326 * main loop. In ascending order of priorities, priorities are
327 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
328 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
329 * G_PRIORITY_DEFAULT. This determines the order in which the
330 * callback will appear in the event list in the main loop, not the
331 * priority which the OS will adopt
332 * @param context The glib main context to which the timeout is to be
333 * attached (the default of NULL will cause the timeout to be attached
334 * to the main program loop, and this is almost always what is
335 * wanted).
336 * @return The glib source id of the timeout.
337 * @note 1. Cancellation of the thread to which the timeout is
338 * attached is blocked during execution of the callback.
339 * @note 2. This function is only compiled into the library if glib >=
340 * 2.14 is installed.
341 * @ingroup timeout
342 */
343 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
344 gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
345
346 /**
347 * Starts a timeout in the glib main loop using the higher granularity
348 * glib timeout-seconds event sources, and executes the callback when
349 * the timeout expires. This version provides for automatic timeout
350 * disconnection when the object whose function the callback
351 * represents is destroyed, via the Releaser object. It is
352 * thread-safe (it may be called in any thread) provided that, if glib
353 * < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does
354 * not require g_thread_init() to be called to be thread-safe.
355 * @param sec The interval of the timeout, in seconds.
356 * @param cb The callback object. Ownership is taken of this object,
357 * and it will be deleted when it has been finished with.
358 * @param r A Releaser object which the protected object has as a
359 * public member.
360 * @param priority The priority to be given to the timeout in the
361 * main loop. In ascending order of priorities, priorities are
362 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
363 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
364 * G_PRIORITY_DEFAULT. This determines the order in which the
365 * callback will appear in the event list in the main loop, not the
366 * priority which the OS will adopt
367 * @param context The glib main context to which the timeout is to be
368 * attached (the default of NULL will cause the timeout to be attached
369 * to the main program loop, and this is almost always what is
370 * wanted).
371 * @return The glib source id of the timeout.
372 * @exception std::bad_alloc This function might throw std::bad_alloc
373 * if memory is exhausted and the system throws in that case. If it
374 * does so, the CallbackArg object will be disposed of.
375 * @exception Cgu::Thread::MutexError This method might throw
376 * Cgu:Thread::MutexError if initialisation of the mutex in a
377 * SafeEmitterArg object constructed by this method fails. If it does
378 * so, the CallbackArg object will be disposed of. (It is often not
379 * worth checking for this exception, as it means either memory is
380 * exhausted or pthread has run out of other resources to create new
381 * mutexes.)
382 * @note 1. Cancellation of the thread to which the timeout is
383 * attached is blocked during execution of the callback.
384 * @note 2. This function is only compiled into the library if glib >=
385 * 2.14 is installed.
386 * @note 3. By virtue of the Releaser object, it is in theory possible
387 * (if memory is exhausted and the system throws in that case) that an
388 * internal SafeEmitterArg object will throw std::bad_alloc when
389 * emitting/executing the timeout callback in the glib main loop, with
390 * the result that the relevant callback will not execute (instead the
391 * exception will be consumed and a g_critical() warning will be
392 * issued) and thus will be delayed until expiry of the next timeout
393 * interval. This is rarely of any relevance because glib will abort
394 * the program if it is itself unable to obtain memory from the
395 * operating system. However, where it is relevant, design the
396 * program so that it is not necessary to provide a releaser object.
397 * @ingroup timeout
398 */
399 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
400 Releaser& r, gint priority = G_PRIORITY_DEFAULT,
401 GMainContext* context = 0);
402
403 /**
404 * Starts a timeout in the glib main loop using the higher granularity
405 * glib timeout-seconds event sources, and executes a callable object
406 * when the timeout expires. It is thread-safe (it may be called in
407 * any thread) provided that, if glib < 2.32 is used, g_thread_init()
408 * has been called. glib >= 2.32 does not require g_thread_init() to
409 * be called to be thread-safe. This function will not throw unless
410 * the copy or move constructor of the callable object throws.
411 * @param sec The interval of the timeout, in seconds.
412 * @param func A callable object, such as formed by a lambda
413 * expression or the result of std::bind. It should take an unbound
414 * bool& argument.
415 * @param priority The priority to be given to the timeout in the
416 * main loop. In ascending order of priorities, priorities are
417 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
418 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
419 * G_PRIORITY_DEFAULT. This determines the order in which the
420 * callback will appear in the event list in the main loop, not the
421 * priority which the OS will adopt
422 * @param context The glib main context to which the timeout is to be
423 * attached (the default of NULL will cause the timeout to be attached
424 * to the main program loop, and this is almost always what is
425 * wanted).
426 * @return The glib source id of the timeout.
427 * @note 1. Cancellation of the thread to which the timeout is
428 * attached is blocked during execution of the callback.
429 * @note 2. This function is only compiled into the library if glib >=
430 * 2.14 is installed.
431 * @ingroup timeout
432 *
433 * Since 2.1.0
434 */
435 template <class F,
436 class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type,
437 const Callback::CallbackArg<bool&>*>::value>::type>
438 // we need to use enable_if so that where this function is passed a
439 // pointer to non-const Callback::CallbackArg, or some other
440 // convertible pointer, this templated overload is dropped from the
441 // overload set, in order to support the Callback::CallbackArg pointer
442 // overloads of this function. This overload calls into the version
443 // of this function taking a pointer to const Callback::CallbackArg in
444 // order to perform type erasure.
445 guint start_timeout_seconds(guint sec, F&& func,
446 gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0) {
447 return start_timeout_seconds(sec, Callback::lambda<bool&>(std::forward<F>(func)),
448 priority, context);
449 }
450
451 /**
452 * Starts a timeout in the glib main loop using the higher granularity
453 * glib timeout-seconds event sources, and executes a callback object
454 * when the timeout expires. This version provides for automatic
455 * timeout disconnection when an object whose function the callback
456 * represents or calls into is destroyed, via the Releaser object. It
457 * is thread-safe (it may be called in any thread) provided that, if
458 * glib < 2.32 is used, g_thread_init() has been called. glib >= 2.32
459 * does not require g_thread_init() to be called to be thread-safe.
460 * @param sec The interval of the timeout, in seconds.
461 * @param func A callable object, such as formed by a lambda
462 * expression or the result of std::bind. It should take an unbound
463 * bool& argument.
464 * @param r A Releaser object which the protected object has as a
465 * public member.
466 * @param priority The priority to be given to the timeout in the
467 * main loop. In ascending order of priorities, priorities are
468 * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
469 * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
470 * G_PRIORITY_DEFAULT. This determines the order in which the
471 * callback will appear in the event list in the main loop, not the
472 * priority which the OS will adopt
473 * @param context The glib main context to which the timeout is to be
474 * attached (the default of NULL will cause the timeout to be attached
475 * to the main program loop, and this is almost always what is
476 * wanted).
477 * @return The glib source id of the timeout.
478 * @exception std::bad_alloc This function might throw std::bad_alloc
479 * if memory is exhausted and the system throws in that case.
480 * @exception Cgu::Thread::MutexError This method might throw
481 * Cgu:Thread::MutexError if initialisation of the mutex in a
482 * SafeEmitterArg object constructed by this method fails. (It is
483 * often not worth checking for this exception, as it means either
484 * memory is exhausted or pthread has run out of other resources to
485 * create new mutexes.)
486 * @note 1. This function may also throw if the copy or move
487 * constructor of the callable object throws.
488 * @note 2. Cancellation of the thread to which the timeout is
489 * attached is blocked during execution of the callback.
490 * @note 3. This function is only compiled into the library if glib >=
491 * 2.14 is installed.
492 * @note 4. By virtue of the Releaser object, it is in theory possible
493 * (if memory is exhausted and the system throws in that case) that an
494 * internal SafeEmitterArg object will throw std::bad_alloc when
495 * emitting/executing the timeout callback in the glib main loop, with
496 * the result that the relevant callback will not execute (instead the
497 * exception will be consumed and a g_critical() warning will be
498 * issued) and thus will be delayed until expiry of the next timeout
499 * interval. This is rarely of any relevance because glib will abort
500 * the program if it is itself unable to obtain memory from the
501 * operating system. However, where it is relevant, design the
502 * program so that it is not necessary to provide a releaser object.
503 * @ingroup timeout
504 *
505 * Since 2.1.0
506 */
507 // we need to use enable_if so that where this function is passed a
508 // pointer to non-const Callback::CallbackArg, or some other
509 // convertible pointer, this templated overload is dropped from the
510 // overload set, in order to support the Callback::CallbackArg pointer
511 // overloads of this function. This overload calls into the version
512 // of this function taking a pointer to const Callback::CallbackArg in
513 // order to perform type erasure.
514 template <class F,
515 class = typename std::enable_if<!std::is_convertible<typename std::remove_reference<F>::type,
516 const Callback::CallbackArg<bool&>*>::value>::type>
517 guint start_timeout_seconds(guint sec, F&& func,
518 Releaser& r, gint priority = G_PRIORITY_DEFAULT,
519 GMainContext* context = 0) {
520 return start_timeout_seconds(sec, Callback::lambda<bool&>(std::forward<F>(func)),
521 r, priority,
522 context);
523 }
524
525 } // namespace Cgu
526
527 #endif