c++-gtk-utils
timeout.h
Go to the documentation of this file.
00001 /* Copyright (C) 2009 Chris Vine
00002 
00003 The library comprised in this file or of which this file is part is
00004 distributed by Chris Vine under the GNU Lesser General Public
00005 License as follows:
00006 
00007    This library is free software; you can redistribute it and/or
00008    modify it under the terms of the GNU Lesser General Public License
00009    as published by the Free Software Foundation; either version 2.1 of
00010    the License, or (at your option) any later version.
00011 
00012    This library is distributed in the hope that it will be useful, but
00013    WITHOUT ANY WARRANTY; without even the implied warranty of
00014    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015    Lesser General Public License, version 2.1, for more details.
00016 
00017    You should have received a copy of the GNU Lesser General Public
00018    License, version 2.1, along with this library (see the file LGPL.TXT
00019    which came with this source code package in the c++-gtk-utils
00020    sub-directory); if not, write to the Free Software Foundation, Inc.,
00021    59 Temple Place - Suite 330, Boston, MA, 02111-1307, USA.
00022 
00023 */
00024 
00025 #ifndef CGU_TIMEOUT_H
00026 #define CGU_TIMEOUT_H
00027 
00028 /**
00029  * @defgroup timeout timeout
00030  *
00031  * \#include <c++-gtk-utils/timeout.h>
00032  *
00033  * The start_timeout() function connects a timeout to an event loop
00034  * owned by a GMainContext object (normally the main program loop).
00035  * By so doing, it provides a convenient way of attaching the callback
00036  * for the timeout, and also provides for automatic disconnection when
00037  * an object whose function the callback represents is destroyed.  The
00038  * timeout will keep executing the callback at the intervals set in
00039  * start_timeout() until it is terminated in one of the ways mentioned
00040  * below.
00041  *
00042  * start_timeout() is thread-safe (it may be called in any thread)
00043  * provided that the glib main loop has been made thread-safe by a
00044  * call to g_thread_init().
00045  *
00046  * start_timeout() takes ownership of the passed Callback object.  The
00047  * function comes in two versions.  The one which takes a
00048  * Callback::Releaser object as its third argument provides for
00049  * automatic termination of the execution of the callback at the
00050  * specified interval if the target object which has the Releaser as a
00051  * member is destroyed.  (Note that for this to be race free, the
00052  * lifetime of the remote target object whose method is to be invoked
00053  * must be determined by the thread to whose main loop the timeout has
00054  * been attached.  When the main loop begins invoking the execution of
00055  * the timeout callback, the remote object must either wholly exist,
00056  * in which case the callback will be invoked, or have been destroyed,
00057  * in which case the callback will be ignored, and not be in some
00058  * transient half-state governed by another thread.)
00059  *
00060  * The connected function encapsulated by the callback passed to
00061  * start_timeout() and executed by the main loop should take a single
00062  * unbound bool& argument (with any other arguments bound in the
00063  * callback).  If that bool& argument is set by the connected function
00064  * to false, then the timeout calls will be ended and all resources
00065  * connected with it deleted without further user action being
00066  * required (there is no need for the connected function to set it to
00067  * true if timeout execution is to continue, as that is the default).
00068  * In addition, the timeout will be ended automatically and resources
00069  * deleted if (i) as mentioned above, the callback passed to
00070  * start_timeout() is protected by a Releaser object and the target
00071  * object whose method is encapsulated by the callback is destroyed,
00072  * or (ii) g_source_remove() is called on the source id returned by
00073  * start_timeout() (where the timeout is attached to the default main
00074  * context) or g_source_destroy() is called on the GSource object
00075  * obtained from that id with g_main_context_find_source_by_id()
00076  * (where the timeout has been attached to a non-default main
00077  * context).  If the source has been removed automatically by virtue
00078  * of the bool& argument being set to false or by virtue of a Releaser
00079  * object releasing, g_source_remove() or g_source_destroy() should
00080  * not afterwards be called in respect of the id value returned by
00081  * start_timeout() in case it has been reused by the main context
00082  * concerned in the meantime.
00083  *
00084  * The start_timeout_seconds() functions do the same as their
00085  * start_timeout() counterparts, except that they use the larger
00086  * granularity glib timeout-seconds main loop event sources (and take
00087  * seconds and not milliseconds as their timeout argument).  The idea
00088  * behind the glib timeout-seconds sources is to group long timeout
00089  * events which do not have critical timing resolution requirements so
00090  * that they are aligned together with one second granularity.  This
00091  * minimises the number of processor wake-ups required to handle such
00092  * events, thereby helping power efficiency.  These functions are to
00093  * be preferred for long timeouts where one second granularity is
00094  * acceptable.  These larger granularity functions are only compiled
00095  * into the library if glib >= 2.14 is installed.
00096  */
00097 
00098 #include <glib.h>
00099 #include <c++-gtk-utils/callback.h>
00100 #include <c++-gtk-utils/cgu_config.h>
00101 
00102 namespace Cgu {
00103 
00104 class Releaser;
00105 
00106 /**
00107  * Starts a timeout in the glib main loop, and executes the callback
00108  * when the timeout expires.  It is thread-safe (it may be called in
00109  * any thread) provided that the glib main loop has been made
00110  * thread-safe by a call to g_thread_init().  This function will not
00111  * throw.
00112  * @param millisec The interval of the timeout, in milliseconds.
00113  * @param cb The callback object.  Ownership is taken of this object,
00114  * and it will be deleted when it has been finished with.
00115  * @param priority The priority to be given to the timeout in the
00116  * main loop.  In ascending order of priorities, priorities are
00117  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
00118  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
00119  * G_PRIORITY_DEFAULT.  This determines the order in which the
00120  * callback will appear in the event list in the main loop, not the
00121  * priority which the OS will adopt
00122  * @param context The glib main context to which the timeout is to be
00123  * attached (the default of NULL will cause the timeout to be attached
00124  * to the main program loop, and this is almost always what is
00125  * wanted).
00126  * @return The glib source id of the timeout.
00127  * @note Cancellation of the thread to which the timeout is attached is
00128  * blocked during execution of the callback.
00129  * @ingroup timeout
00130  */
00131 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
00132                     gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
00133 
00134 /**
00135  * Starts a timeout in the glib main loop, and executes the callback
00136  * when the timeout expires.  This version provides for automatic
00137  * timeout disconnection when the object whose function the callback
00138  * represents is destroyed, via the Releaser object.  It is
00139  * thread-safe (it may be called in any thread) provided that the glib
00140  * main loop has been made thread-safe by a call to g_thread_init().
00141  * @param millisec The interval of the timeout, in milliseconds.
00142  * @param cb The callback object.  Ownership is taken of this object,
00143  * and it will be deleted when it has been finished with.
00144  * @param r A Releaser object which the protected object has as a
00145  * public member.
00146  * @param priority The priority to be given to the timeout in the
00147  * main loop.  In ascending order of priorities, priorities are
00148  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
00149  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
00150  * G_PRIORITY_DEFAULT.  This determines the order in which the
00151  * callback will appear in the event list in the main loop, not the
00152  * priority which the OS will adopt
00153  * @param context The glib main context to which the timeout is to be
00154  * attached (the default of NULL will cause the timeout to be attached
00155  * to the main program loop, and this is almost always what is
00156  * wanted).
00157  * @return The glib source id of the timeout.
00158  * @exception std::bad_alloc This function might throw std::bad_alloc
00159  * if memory is exhausted and the system throws in that case.  If it
00160  * does so, the CallbackArg object will be disposed of.
00161  * @exception Cgu::Thread::MutexError This method might throw
00162  * Cgu:Thread::MutexError if initialisation of the mutex in a
00163  * SafeEmitterArg object constructed by this method fails.  If it does
00164  * so, the CallbackArg object will be disposed of.  (It is often not
00165  * worth checking for this exception, as it means either memory is
00166  * exhausted or pthread has run out of other resources to create new
00167  * mutexes.)
00168  * @note Cancellation of the thread to which the timeout is attached is
00169  * blocked during execution of the callback.
00170  * @ingroup timeout
00171  */
00172 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
00173                     Releaser& r, gint priority = G_PRIORITY_DEFAULT,
00174                     GMainContext* context = 0);
00175 
00176 /**
00177  * Starts a timeout in the glib main loop using the higher granularity
00178  * glib timeout-seconds event sources, and executes the callback when
00179  * the timeout expires.  It is thread-safe (it may be called in any
00180  * thread) provided that the glib main loop has been made thread-safe
00181  * by a call to g_thread_init().  This function will not throw.
00182  * @param sec The interval of the timeout, in seconds.
00183  * @param cb The callback object.  Ownership is taken of this object,
00184  * and it will be deleted when it has been finished with.
00185  * @param priority The priority to be given to the timeout in the
00186  * main loop.  In ascending order of priorities, priorities are
00187  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
00188  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
00189  * G_PRIORITY_DEFAULT.  This determines the order in which the
00190  * callback will appear in the event list in the main loop, not the
00191  * priority which the OS will adopt
00192  * @param context The glib main context to which the timeout is to be
00193  * attached (the default of NULL will cause the timeout to be attached
00194  * to the main program loop, and this is almost always what is
00195  * wanted).
00196  * @return The glib source id of the timeout.
00197  * @note 1. Cancellation of the thread to which the timeout is
00198  * attached is blocked during execution of the callback.
00199  * @note 2. This function is only compiled into the library if glib >=
00200  * 2.14 is installed.
00201  * @ingroup timeout
00202  */
00203 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
00204                             gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
00205 
00206 /**
00207  * Starts a timeout in the glib main loop using the higher granularity
00208  * glib timeout-seconds event sources, and executes the callback when
00209  * the timeout expires.  This version provides for automatic timeout
00210  * disconnection when the object whose function the callback
00211  * represents is destroyed, via the Releaser object.  It is
00212  * thread-safe (it may be called in any thread) provided that the glib
00213  * main loop has been made thread-safe by a call to g_thread_init().
00214  * @param sec The interval of the timeout, in seconds.
00215  * @param cb The callback object.  Ownership is taken of this object,
00216  * and it will be deleted when it has been finished with.
00217  * @param r A Releaser object which the protected object has as a
00218  * public member.
00219  * @param priority The priority to be given to the timeout in the
00220  * main loop.  In ascending order of priorities, priorities are
00221  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
00222  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
00223  * G_PRIORITY_DEFAULT.  This determines the order in which the
00224  * callback will appear in the event list in the main loop, not the
00225  * priority which the OS will adopt
00226  * @param context The glib main context to which the timeout is to be
00227  * attached (the default of NULL will cause the timeout to be attached
00228  * to the main program loop, and this is almost always what is
00229  * wanted).
00230  * @return The glib source id of the timeout.
00231  * @exception std::bad_alloc This function might throw std::bad_alloc
00232  * if memory is exhausted and the system throws in that case.  If it
00233  * does so, the CallbackArg object will be disposed of.
00234  * @exception Cgu::Thread::MutexError This method might throw
00235  * Cgu:Thread::MutexError if initialisation of the mutex in a
00236  * SafeEmitterArg object constructed by this method fails.  If it does
00237  * so, the CallbackArg object will be disposed of.  (It is often not
00238  * worth checking for this exception, as it means either memory is
00239  * exhausted or pthread has run out of other resources to create new
00240  * mutexes.)
00241  * @note 1. Cancellation of the thread to which the timeout is
00242  * attached is blocked during execution of the callback.
00243  * @note 2. This function is only compiled into the library if glib >=
00244  * 2.14 is installed.
00245  * @ingroup timeout
00246  */
00247 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
00248                             Releaser& r, gint priority = G_PRIORITY_DEFAULT,
00249                             GMainContext* context = 0);
00250 
00251 } // namespace Cgu
00252 
00253 #endif