c++-gtk-utils
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  * start_timeout() is thread-safe (it may be called in any thread)
43  * provided that, if glib < 2.32 is used, the glib main loop has been
44  * made thread-safe by a call to g_thread_init(). glib >= 2.32 does
45  * not require g_thread_init() to be called in order to be
46  * thread-safe.
47  *
48  * start_timeout() takes ownership of the passed Callback object. The
49  * function comes in two versions. The one which takes a
50  * Callback::Releaser object as its third argument provides for
51  * automatic termination of the execution of the callback at the
52  * specified interval if the target object which has the Releaser as a
53  * member is destroyed. (Note that for this to be race free, the
54  * lifetime of the remote target object whose method is to be invoked
55  * must be determined by the thread to whose main loop the timeout has
56  * been attached. When the main loop begins invoking the execution of
57  * the timeout callback, the remote object must either wholly exist,
58  * in which case the callback will be invoked, or have been destroyed,
59  * in which case the callback will be ignored, and not be in some
60  * transient half-state governed by another thread.)
61  *
62  * The connected function encapsulated by the callback passed to
63  * start_timeout() and executed by the main loop should take a single
64  * unbound bool& argument (with any other arguments bound in the
65  * callback). If that bool& argument is set by the connected function
66  * to false, then the timeout calls will be ended and all resources
67  * connected with it deleted without further user action being
68  * required (there is no need for the connected function to set it to
69  * true if timeout execution is to continue, as that is the default).
70  * In addition, the timeout will be ended automatically and resources
71  * deleted if (i) as mentioned above, the callback passed to
72  * start_timeout() is protected by a Releaser object and the target
73  * object whose method is encapsulated by the callback is destroyed,
74  * or (ii) g_source_remove() is called on the source id returned by
75  * start_timeout() (where the timeout is attached to the default main
76  * context) or g_source_destroy() is called on the GSource object
77  * obtained from that id with g_main_context_find_source_by_id()
78  * (where the timeout has been attached to a non-default main
79  * context). If the source has been removed automatically by virtue
80  * of the bool& argument being set to false or by virtue of a Releaser
81  * object releasing, g_source_remove() or g_source_destroy() should
82  * not afterwards be called in respect of the id value returned by
83  * start_timeout() in case it has been reused by the main context
84  * concerned in the meantime.
85  *
86  * The start_timeout_seconds() functions do the same as their
87  * start_timeout() counterparts, except that they use the larger
88  * granularity glib timeout-seconds main loop event sources (and take
89  * seconds and not milliseconds as their timeout argument). The idea
90  * behind the glib timeout-seconds sources is to group long timeout
91  * events which do not have critical timing resolution requirements so
92  * that they are aligned together with one second granularity. This
93  * minimises the number of processor wake-ups required to handle such
94  * events, thereby helping power efficiency. These functions are to
95  * be preferred for long timeouts where one second granularity is
96  * acceptable. These larger granularity functions are only compiled
97  * into the library if glib >= 2.14 is installed.
98  */
99 
100 #include <glib.h>
101 #include <c++-gtk-utils/callback.h>
103 
104 namespace Cgu {
105 
106 class Releaser;
107 
108 /**
109  * Starts a timeout in the glib main loop, and executes the callback
110  * when the timeout expires. It is thread-safe (it may be called in
111  * any thread) provided that, if glib < 2.32 is used, g_thread_init()
112  * has been called. glib >= 2.32 does not require g_thread_init() to
113  * be called to be thread-safe. This function will not throw.
114  * @param millisec The interval of the timeout, in milliseconds.
115  * @param cb The callback object. Ownership is taken of this object,
116  * and it will be deleted when it has been finished with.
117  * @param priority The priority to be given to the timeout in the
118  * main loop. In ascending order of priorities, priorities are
119  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
120  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
121  * G_PRIORITY_DEFAULT. This determines the order in which the
122  * callback will appear in the event list in the main loop, not the
123  * priority which the OS will adopt
124  * @param context The glib main context to which the timeout is to be
125  * attached (the default of NULL will cause the timeout to be attached
126  * to the main program loop, and this is almost always what is
127  * wanted).
128  * @return The glib source id of the timeout.
129  * @note 1. Cancellation of the thread to which the timeout is
130  * attached is blocked during execution of the callback.
131  * @note 2. If the callback throws an exception, the exception will be
132  * consumed to protect the main loop and a g_critical() warning will
133  * be issued.
134  * @ingroup timeout
135  */
136 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
137  gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
138 
139 /**
140  * Starts a timeout in the glib main loop, and executes the callback
141  * when the timeout expires. This version provides for automatic
142  * timeout disconnection when the object whose function the callback
143  * represents is destroyed, via the Releaser object. It is
144  * thread-safe (it may be called in any thread) provided that, if glib
145  * < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does
146  * not require g_thread_init() to be called to be thread-safe.
147  * @param millisec The interval of the timeout, in milliseconds.
148  * @param cb The callback object. Ownership is taken of this object,
149  * and it will be deleted when it has been finished with.
150  * @param r A Releaser object which the protected object has as a
151  * public member.
152  * @param priority The priority to be given to the timeout in the
153  * main loop. In ascending order of priorities, priorities are
154  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
155  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
156  * G_PRIORITY_DEFAULT. This determines the order in which the
157  * callback will appear in the event list in the main loop, not the
158  * priority which the OS will adopt
159  * @param context The glib main context to which the timeout is to be
160  * attached (the default of NULL will cause the timeout to be attached
161  * to the main program loop, and this is almost always what is
162  * wanted).
163  * @return The glib source id of the timeout.
164  * @exception std::bad_alloc This function might throw std::bad_alloc
165  * if memory is exhausted and the system throws in that case. If it
166  * does so, the CallbackArg object will be disposed of.
167  * @exception Cgu::Thread::MutexError This function might throw
168  * Cgu:Thread::MutexError if initialisation of the mutex in a
169  * SafeEmitterArg object constructed by this function fails. If it
170  * does so, the CallbackArg object will be disposed of. (It is often
171  * not worth checking for this exception, as it means either memory is
172  * exhausted or pthread has run out of other resources to create new
173  * mutexes.)
174  * @note 1. Cancellation of the thread to which the timeout is
175  * attached is blocked during execution of the callback.
176  * @note 2. If the callback throws an exception, the exception will be
177  * consumed to protect the main loop and a g_critical() warning will
178  * be issued.
179  * @note 3. By virtue of the Releaser object, it is in theory possible
180  * (if memory is exhausted and the system throws in that case) that an
181  * internal SafeEmitterArg object will throw std::bad_alloc when
182  * emitting/executing the timeout callback in the glib main loop, with
183  * the result that the relevant callback will not execute (instead the
184  * exception will be consumed and a g_critical() warning will be
185  * issued) and thus will be delayed until expiry of the next timeout
186  * interval. This is rarely of any relevance because glib will abort
187  * the program if it is itself unable to obtain memory from the
188  * operating system. However, where it is relevant, design the
189  * program so that it is not necessary to provide a releaser object.
190  * @ingroup timeout
191  */
192 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
193  Releaser& r, gint priority = G_PRIORITY_DEFAULT,
194  GMainContext* context = 0);
195 
196 /**
197  * Starts a timeout in the glib main loop using the higher granularity
198  * glib timeout-seconds event sources, and executes the callback when
199  * the timeout expires. It is thread-safe (it may be called in any
200  * thread) provided that, if glib < 2.32 is used, g_thread_init() has
201  * been called. glib >= 2.32 does not require g_thread_init() to be
202  * called to be thread-safe. This function will not throw.
203  * @param sec The interval of the timeout, in seconds.
204  * @param cb The callback object. Ownership is taken of this object,
205  * and it will be deleted when it has been finished with.
206  * @param priority The priority to be given to the timeout in the
207  * main loop. In ascending order of priorities, priorities are
208  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
209  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
210  * G_PRIORITY_DEFAULT. This determines the order in which the
211  * callback will appear in the event list in the main loop, not the
212  * priority which the OS will adopt
213  * @param context The glib main context to which the timeout is to be
214  * attached (the default of NULL will cause the timeout to be attached
215  * to the main program loop, and this is almost always what is
216  * wanted).
217  * @return The glib source id of the timeout.
218  * @note 1. Cancellation of the thread to which the timeout is
219  * attached is blocked during execution of the callback.
220  * @note 2. If the callback throws an exception, the exception will be
221  * consumed to protect the main loop and a g_critical() warning will
222  * be issued.
223  * @note 3. This function is only compiled into the library if glib >=
224  * 2.14 is installed.
225  * @ingroup timeout
226  */
227 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
228  gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
229 
230 /**
231  * Starts a timeout in the glib main loop using the higher granularity
232  * glib timeout-seconds event sources, and executes the callback when
233  * the timeout expires. This version provides for automatic timeout
234  * disconnection when the object whose function the callback
235  * represents is destroyed, via the Releaser object. It is
236  * thread-safe (it may be called in any thread) provided that, if glib
237  * < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does
238  * not require g_thread_init() to be called to be thread-safe.
239  * @param sec The interval of the timeout, in seconds.
240  * @param cb The callback object. Ownership is taken of this object,
241  * and it will be deleted when it has been finished with.
242  * @param r A Releaser object which the protected object has as a
243  * public member.
244  * @param priority The priority to be given to the timeout in the
245  * main loop. In ascending order of priorities, priorities are
246  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
247  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
248  * G_PRIORITY_DEFAULT. This determines the order in which the
249  * callback will appear in the event list in the main loop, not the
250  * priority which the OS will adopt
251  * @param context The glib main context to which the timeout is to be
252  * attached (the default of NULL will cause the timeout to be attached
253  * to the main program loop, and this is almost always what is
254  * wanted).
255  * @return The glib source id of the timeout.
256  * @exception std::bad_alloc This function might throw std::bad_alloc
257  * if memory is exhausted and the system throws in that case. If it
258  * does so, the CallbackArg object will be disposed of.
259  * @exception Cgu::Thread::MutexError This function might throw
260  * Cgu:Thread::MutexError if initialisation of the mutex in a
261  * SafeEmitterArg object constructed by this function fails. If it
262  * does so, the CallbackArg object will be disposed of. (It is often
263  * not worth checking for this exception, as it means either memory is
264  * exhausted or pthread has run out of other resources to create new
265  * mutexes.)
266  * @note 1. Cancellation of the thread to which the timeout is
267  * attached is blocked during execution of the callback.
268  * @note 2. If the callback throws an exception, the exception will be
269  * consumed to protect the main loop and a g_critical() warning will
270  * be issued.
271  * @note 3. This function is only compiled into the library if glib >=
272  * 2.14 is installed.
273  * @note 4. By virtue of the Releaser object, it is in theory possible
274  * (if memory is exhausted and the system throws in that case) that an
275  * internal SafeEmitterArg object will throw std::bad_alloc when
276  * emitting/executing the timeout callback in the glib main loop, with
277  * the result that the relevant callback will not execute (instead the
278  * exception will be consumed and a g_critical() warning will be
279  * issued) and thus will be delayed until expiry of the next timeout
280  * interval. This is rarely of any relevance because glib will abort
281  * the program if it is itself unable to obtain memory from the
282  * operating system. However, where it is relevant, design the
283  * program so that it is not necessary to provide a releaser object.
284  * @ingroup timeout
285  */
286 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
287  Releaser& r, gint priority = G_PRIORITY_DEFAULT,
288  GMainContext* context = 0);
289 
290 } // namespace Cgu
291 
292 #endif
Cgu
Definition: application.h:44
Cgu::start_timeout_seconds
guint start_timeout_seconds(guint sec, const Callback::CallbackArg< bool & > *cb, gint priority=G_PRIORITY_DEFAULT, GMainContext *context=0)
callback.h
This file provides classes for type erasure.
Cgu::start_timeout
guint start_timeout(guint millisec, const Callback::CallbackArg< bool & > *cb, gint priority=G_PRIORITY_DEFAULT, GMainContext *context=0)
cgu_config.h