c++-gtk-utils
timeout.h
Go to the documentation of this file.
1 /* Copyright (C) 2009 and 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 */
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 Cancellation of the thread to which the timeout is attached is
130  * blocked during execution of the callback.
131  * @ingroup timeout
132  */
133 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
134  gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
135 
136 /**
137  * Starts a timeout in the glib main loop, and executes the callback
138  * when the timeout expires. This version provides for automatic
139  * timeout disconnection when the object whose function the callback
140  * represents is destroyed, via the Releaser object. It is
141  * thread-safe (it may be called in any thread) provided that, if glib
142  * < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does
143  * not require g_thread_init() to be called to be thread-safe.
144  * @param millisec The interval of the timeout, in milliseconds.
145  * @param cb The callback object. Ownership is taken of this object,
146  * and it will be deleted when it has been finished with.
147  * @param r A Releaser object which the protected object has as a
148  * public member.
149  * @param priority The priority to be given to the timeout in the
150  * main loop. In ascending order of priorities, priorities are
151  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
152  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
153  * G_PRIORITY_DEFAULT. This determines the order in which the
154  * callback will appear in the event list in the main loop, not the
155  * priority which the OS will adopt
156  * @param context The glib main context to which the timeout is to be
157  * attached (the default of NULL will cause the timeout to be attached
158  * to the main program loop, and this is almost always what is
159  * wanted).
160  * @return The glib source id of the timeout.
161  * @exception std::bad_alloc This function might throw std::bad_alloc
162  * if memory is exhausted and the system throws in that case. If it
163  * does so, the CallbackArg object will be disposed of.
164  * @exception Cgu::Thread::MutexError This method might throw
165  * Cgu:Thread::MutexError if initialisation of the mutex in a
166  * SafeEmitterArg object constructed by this method fails. If it does
167  * so, the CallbackArg object will be disposed of. (It is often not
168  * worth checking for this exception, as it means either memory is
169  * exhausted or pthread has run out of other resources to create new
170  * mutexes.)
171  * @note 1. Cancellation of the thread to which the timeout is
172  * attached is blocked during execution of the callback.
173  * @note 2. By virtue of the Releaser object, it is in theory possible
174  * (if memory is exhausted and the system throws in that case) that an
175  * internal SafeEmitterArg object will throw std::bad_alloc when
176  * emitting/executing the timeout callback in the glib main loop, with
177  * the result that the relevant callback will not execute (instead the
178  * exception will be consumed and a g_critical() warning will be
179  * issued) and thus will be delayed until expiry of the next timeout
180  * interval. This is rarely of any relevance because glib will abort
181  * the program if it is itself unable to obtain memory from the
182  * operating system. However, where it is relevant, design the
183  * program so that it is not necessary to provide a releaser object.
184  * @ingroup timeout
185  */
186 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
187  Releaser& r, gint priority = G_PRIORITY_DEFAULT,
188  GMainContext* context = 0);
189 
190 /**
191  * Starts a timeout in the glib main loop using the higher granularity
192  * glib timeout-seconds event sources, and executes the callback when
193  * the timeout expires. It is thread-safe (it may be called in any
194  * thread) provided that, if glib < 2.32 is used, g_thread_init() has
195  * been called. glib >= 2.32 does not require g_thread_init() to be
196  * called to be thread-safe. This function will not throw.
197  * @param sec The interval of the timeout, in seconds.
198  * @param cb The callback object. Ownership is taken of this object,
199  * and it will be deleted when it has been finished with.
200  * @param priority The priority to be given to the timeout in the
201  * main loop. In ascending order of priorities, priorities are
202  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
203  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
204  * G_PRIORITY_DEFAULT. This determines the order in which the
205  * callback will appear in the event list in the main loop, not the
206  * priority which the OS will adopt
207  * @param context The glib main context to which the timeout is to be
208  * attached (the default of NULL will cause the timeout to be attached
209  * to the main program loop, and this is almost always what is
210  * wanted).
211  * @return The glib source id of the timeout.
212  * @note 1. Cancellation of the thread to which the timeout is
213  * attached is blocked during execution of the callback.
214  * @note 2. This function is only compiled into the library if glib >=
215  * 2.14 is installed.
216  * @ingroup timeout
217  */
218 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
219  gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
220 
221 /**
222  * Starts a timeout in the glib main loop using the higher granularity
223  * glib timeout-seconds event sources, and executes the callback when
224  * the timeout expires. This version provides for automatic timeout
225  * disconnection when the object whose function the callback
226  * represents is destroyed, via the Releaser object. It is
227  * thread-safe (it may be called in any thread) provided that, if glib
228  * < 2.32 is used, g_thread_init() has been called. glib >= 2.32 does
229  * not require g_thread_init() to be called to be thread-safe.
230  * @param sec The interval of the timeout, in seconds.
231  * @param cb The callback object. Ownership is taken of this object,
232  * and it will be deleted when it has been finished with.
233  * @param r A Releaser object which the protected object has as a
234  * public member.
235  * @param priority The priority to be given to the timeout in the
236  * main loop. In ascending order of priorities, priorities are
237  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
238  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
239  * G_PRIORITY_DEFAULT. This determines the order in which the
240  * callback will appear in the event list in the main loop, not the
241  * priority which the OS will adopt
242  * @param context The glib main context to which the timeout is to be
243  * attached (the default of NULL will cause the timeout to be attached
244  * to the main program loop, and this is almost always what is
245  * wanted).
246  * @return The glib source id of the timeout.
247  * @exception std::bad_alloc This function might throw std::bad_alloc
248  * if memory is exhausted and the system throws in that case. If it
249  * does so, the CallbackArg object will be disposed of.
250  * @exception Cgu::Thread::MutexError This method might throw
251  * Cgu:Thread::MutexError if initialisation of the mutex in a
252  * SafeEmitterArg object constructed by this method fails. If it does
253  * so, the CallbackArg object will be disposed of. (It is often not
254  * worth checking for this exception, as it means either memory is
255  * exhausted or pthread has run out of other resources to create new
256  * mutexes.)
257  * @note 1. Cancellation of the thread to which the timeout is
258  * attached is blocked during execution of the callback.
259  * @note 2. This function is only compiled into the library if glib >=
260  * 2.14 is installed.
261  * @note 3. By virtue of the Releaser object, it is in theory possible
262  * (if memory is exhausted and the system throws in that case) that an
263  * internal SafeEmitterArg object will throw std::bad_alloc when
264  * emitting/executing the timeout callback in the glib main loop, with
265  * the result that the relevant callback will not execute (instead the
266  * exception will be consumed and a g_critical() warning will be
267  * issued) and thus will be delayed until expiry of the next timeout
268  * interval. This is rarely of any relevance because glib will abort
269  * the program if it is itself unable to obtain memory from the
270  * operating system. However, where it is relevant, design the
271  * program so that it is not necessary to provide a releaser object.
272  * @ingroup timeout
273  */
274 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
275  Releaser& r, gint priority = G_PRIORITY_DEFAULT,
276  GMainContext* context = 0);
277 
278 } // namespace Cgu
279 
280 #endif