c++-gtk-utils
timeout.h
Go to the documentation of this file.
00001 /* Copyright (C) 2009 and 2012 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    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 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, if glib < 2.32 is used, the glib main loop has been
00044  * made thread-safe by a call to g_thread_init().  glib >= 2.32 does
00045  * not require g_thread_init() to be called in order to be
00046  * thread-safe.
00047  *
00048  * start_timeout() takes ownership of the passed Callback object.  The
00049  * function comes in two versions.  The one which takes a
00050  * Callback::Releaser object as its third argument provides for
00051  * automatic termination of the execution of the callback at the
00052  * specified interval if the target object which has the Releaser as a
00053  * member is destroyed.  (Note that for this to be race free, the
00054  * lifetime of the remote target object whose method is to be invoked
00055  * must be determined by the thread to whose main loop the timeout has
00056  * been attached.  When the main loop begins invoking the execution of
00057  * the timeout callback, the remote object must either wholly exist,
00058  * in which case the callback will be invoked, or have been destroyed,
00059  * in which case the callback will be ignored, and not be in some
00060  * transient half-state governed by another thread.)
00061  *
00062  * The connected function encapsulated by the callback passed to
00063  * start_timeout() and executed by the main loop should take a single
00064  * unbound bool& argument (with any other arguments bound in the
00065  * callback).  If that bool& argument is set by the connected function
00066  * to false, then the timeout calls will be ended and all resources
00067  * connected with it deleted without further user action being
00068  * required (there is no need for the connected function to set it to
00069  * true if timeout execution is to continue, as that is the default).
00070  * In addition, the timeout will be ended automatically and resources
00071  * deleted if (i) as mentioned above, the callback passed to
00072  * start_timeout() is protected by a Releaser object and the target
00073  * object whose method is encapsulated by the callback is destroyed,
00074  * or (ii) g_source_remove() is called on the source id returned by
00075  * start_timeout() (where the timeout is attached to the default main
00076  * context) or g_source_destroy() is called on the GSource object
00077  * obtained from that id with g_main_context_find_source_by_id()
00078  * (where the timeout has been attached to a non-default main
00079  * context).  If the source has been removed automatically by virtue
00080  * of the bool& argument being set to false or by virtue of a Releaser
00081  * object releasing, g_source_remove() or g_source_destroy() should
00082  * not afterwards be called in respect of the id value returned by
00083  * start_timeout() in case it has been reused by the main context
00084  * concerned in the meantime.
00085  *
00086  * The start_timeout_seconds() functions do the same as their
00087  * start_timeout() counterparts, except that they use the larger
00088  * granularity glib timeout-seconds main loop event sources (and take
00089  * seconds and not milliseconds as their timeout argument).  The idea
00090  * behind the glib timeout-seconds sources is to group long timeout
00091  * events which do not have critical timing resolution requirements so
00092  * that they are aligned together with one second granularity.  This
00093  * minimises the number of processor wake-ups required to handle such
00094  * events, thereby helping power efficiency.  These functions are to
00095  * be preferred for long timeouts where one second granularity is
00096  * acceptable.  These larger granularity functions are only compiled
00097  * into the library if glib >= 2.14 is installed.
00098  */
00099 
00100 #include <glib.h>
00101 #include <c++-gtk-utils/callback.h>
00102 #include <c++-gtk-utils/cgu_config.h>
00103 
00104 namespace Cgu {
00105 
00106 class Releaser;
00107 
00108 /**
00109  * Starts a timeout in the glib main loop, and executes the callback
00110  * when the timeout expires.  It is thread-safe (it may be called in
00111  * any thread) provided that, if glib < 2.32 is used, g_thread_init()
00112  * has been called.  glib >= 2.32 does not require g_thread_init() to
00113  * be called to be thread-safe.  This function will not throw.
00114  * @param millisec The interval of the timeout, in milliseconds.
00115  * @param cb The callback object.  Ownership is taken of this object,
00116  * and it will be deleted when it has been finished with.
00117  * @param priority The priority to be given to the timeout in the
00118  * main loop.  In ascending order of priorities, priorities are
00119  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
00120  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
00121  * G_PRIORITY_DEFAULT.  This determines the order in which the
00122  * callback will appear in the event list in the main loop, not the
00123  * priority which the OS will adopt
00124  * @param context The glib main context to which the timeout is to be
00125  * attached (the default of NULL will cause the timeout to be attached
00126  * to the main program loop, and this is almost always what is
00127  * wanted).
00128  * @return The glib source id of the timeout.
00129  * @note Cancellation of the thread to which the timeout is attached is
00130  * blocked during execution of the callback.
00131  * @ingroup timeout
00132  */
00133 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
00134                     gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
00135 
00136 /**
00137  * Starts a timeout in the glib main loop, and executes the callback
00138  * when the timeout expires.  This version provides for automatic
00139  * timeout disconnection when the object whose function the callback
00140  * represents is destroyed, via the Releaser object.  It is
00141  * thread-safe (it may be called in any thread) provided that, if glib
00142  * < 2.32 is used, g_thread_init() has been called.  glib >= 2.32 does
00143  * not require g_thread_init() to be called to be thread-safe.
00144  * @param millisec The interval of the timeout, in milliseconds.
00145  * @param cb The callback object.  Ownership is taken of this object,
00146  * and it will be deleted when it has been finished with.
00147  * @param r A Releaser object which the protected object has as a
00148  * public member.
00149  * @param priority The priority to be given to the timeout in the
00150  * main loop.  In ascending order of priorities, priorities are
00151  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
00152  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
00153  * G_PRIORITY_DEFAULT.  This determines the order in which the
00154  * callback will appear in the event list in the main loop, not the
00155  * priority which the OS will adopt
00156  * @param context The glib main context to which the timeout is to be
00157  * attached (the default of NULL will cause the timeout to be attached
00158  * to the main program loop, and this is almost always what is
00159  * wanted).
00160  * @return The glib source id of the timeout.
00161  * @exception std::bad_alloc This function might throw std::bad_alloc
00162  * if memory is exhausted and the system throws in that case.  If it
00163  * does so, the CallbackArg object will be disposed of.
00164  * @exception Cgu::Thread::MutexError This method might throw
00165  * Cgu:Thread::MutexError if initialisation of the mutex in a
00166  * SafeEmitterArg object constructed by this method fails.  If it does
00167  * so, the CallbackArg object will be disposed of.  (It is often not
00168  * worth checking for this exception, as it means either memory is
00169  * exhausted or pthread has run out of other resources to create new
00170  * mutexes.)
00171  * @note Cancellation of the thread to which the timeout is attached is
00172  * blocked during execution of the callback.
00173  * @ingroup timeout
00174  */
00175 guint start_timeout(guint millisec, const Callback::CallbackArg<bool&>* cb,
00176                     Releaser& r, gint priority = G_PRIORITY_DEFAULT,
00177                     GMainContext* context = 0);
00178 
00179 /**
00180  * Starts a timeout in the glib main loop using the higher granularity
00181  * glib timeout-seconds event sources, and executes the callback when
00182  * the timeout expires.  It is thread-safe (it may be called in any
00183  * thread) provided that, if glib < 2.32 is used, g_thread_init() has
00184  * been called.  glib >= 2.32 does not require g_thread_init() to be
00185  * called to be thread-safe.  This function will not throw.
00186  * @param sec The interval of the timeout, in seconds.
00187  * @param cb The callback object.  Ownership is taken of this object,
00188  * and it will be deleted when it has been finished with.
00189  * @param priority The priority to be given to the timeout in the
00190  * main loop.  In ascending order of priorities, priorities are
00191  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
00192  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
00193  * G_PRIORITY_DEFAULT.  This determines the order in which the
00194  * callback will appear in the event list in the main loop, not the
00195  * priority which the OS will adopt
00196  * @param context The glib main context to which the timeout is to be
00197  * attached (the default of NULL will cause the timeout to be attached
00198  * to the main program loop, and this is almost always what is
00199  * wanted).
00200  * @return The glib source id of the timeout.
00201  * @note 1. Cancellation of the thread to which the timeout is
00202  * attached is blocked during execution of the callback.
00203  * @note 2. This function is only compiled into the library if glib >=
00204  * 2.14 is installed.
00205  * @ingroup timeout
00206  */
00207 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
00208                             gint priority = G_PRIORITY_DEFAULT, GMainContext* context = 0);
00209 
00210 /**
00211  * Starts a timeout in the glib main loop using the higher granularity
00212  * glib timeout-seconds event sources, and executes the callback when
00213  * the timeout expires.  This version provides for automatic timeout
00214  * disconnection when the object whose function the callback
00215  * represents is destroyed, via the Releaser object.  It is
00216  * thread-safe (it may be called in any thread) provided that, if glib
00217  * < 2.32 is used, g_thread_init() has been called.  glib >= 2.32 does
00218  * not require g_thread_init() to be called to be thread-safe.
00219  * @param sec The interval of the timeout, in seconds.
00220  * @param cb The callback object.  Ownership is taken of this object,
00221  * and it will be deleted when it has been finished with.
00222  * @param r A Releaser object which the protected object has as a
00223  * public member.
00224  * @param priority The priority to be given to the timeout in the
00225  * main loop.  In ascending order of priorities, priorities are
00226  * G_PRIORITY_LOW, G_PRIORITY_DEFAULT_IDLE, G_PRIORITY_HIGH_IDLE,
00227  * G_PRIORITY_DEFAULT and G_PRIORITY_HIGH. The default is
00228  * G_PRIORITY_DEFAULT.  This determines the order in which the
00229  * callback will appear in the event list in the main loop, not the
00230  * priority which the OS will adopt
00231  * @param context The glib main context to which the timeout is to be
00232  * attached (the default of NULL will cause the timeout to be attached
00233  * to the main program loop, and this is almost always what is
00234  * wanted).
00235  * @return The glib source id of the timeout.
00236  * @exception std::bad_alloc This function might throw std::bad_alloc
00237  * if memory is exhausted and the system throws in that case.  If it
00238  * does so, the CallbackArg object will be disposed of.
00239  * @exception Cgu::Thread::MutexError This method might throw
00240  * Cgu:Thread::MutexError if initialisation of the mutex in a
00241  * SafeEmitterArg object constructed by this method fails.  If it does
00242  * so, the CallbackArg object will be disposed of.  (It is often not
00243  * worth checking for this exception, as it means either memory is
00244  * exhausted or pthread has run out of other resources to create new
00245  * mutexes.)
00246  * @note 1. Cancellation of the thread to which the timeout is
00247  * attached is blocked during execution of the callback.
00248  * @note 2. This function is only compiled into the library if glib >=
00249  * 2.14 is installed.
00250  * @ingroup timeout
00251  */
00252 guint start_timeout_seconds(guint sec, const Callback::CallbackArg<bool&>* cb,
00253                             Releaser& r, gint priority = G_PRIORITY_DEFAULT,
00254                             GMainContext* context = 0);
00255 
00256 } // namespace Cgu
00257 
00258 #endif