mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-25 15:06:14 +01:00
Add functions for approximate timeouts
This commit is contained in:
parent
4a7aeef16f
commit
f8c1c1f9e0
@ -1,5 +1,9 @@
|
||||
2006-09-10 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/glib.symbols:
|
||||
* glib/gmain.[hc]: Add functions to create approximate
|
||||
timeouts. (#353942, Arjan van de Ven)
|
||||
|
||||
* glib/gstdio.c (g_rename): Initialize save_errno.
|
||||
(#355206, Mike Edenfield)
|
||||
|
||||
|
@ -1,3 +1,7 @@
|
||||
2006-09-10 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/glib-sections.txt: Add new functions
|
||||
|
||||
2006-08-28 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
* glib/compiling.sgml: Add a note about G_DISABLE_DEPRECATED.
|
||||
|
@ -437,8 +437,10 @@ g_main_set_poll_func
|
||||
|
||||
<SUBSECTION>
|
||||
g_timeout_source_new
|
||||
g_timeout_source_new_seconds
|
||||
g_timeout_add
|
||||
g_timeout_add_full
|
||||
g_timeout_add_seconds
|
||||
|
||||
<SUBSECTION>
|
||||
g_idle_source_new
|
||||
|
@ -617,8 +617,10 @@ g_idle_add_full
|
||||
g_idle_remove_by_data
|
||||
g_idle_source_new
|
||||
g_timeout_add
|
||||
g_timeout_add_seconds
|
||||
g_timeout_add_full
|
||||
g_timeout_source_new
|
||||
g_timeout_source_new_seconds
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
151
glib/gmain.c
151
glib/gmain.c
@ -41,6 +41,7 @@
|
||||
#include <signal.h>
|
||||
#include <sys/types.h>
|
||||
#include <time.h>
|
||||
#include <stdlib.h>
|
||||
#ifdef HAVE_SYS_TIME_H
|
||||
#include <sys/time.h>
|
||||
#endif /* HAVE_SYS_TIME_H */
|
||||
@ -179,6 +180,7 @@ struct _GTimeoutSource
|
||||
GSource source;
|
||||
GTimeVal expiration;
|
||||
guint interval;
|
||||
guint granularity;
|
||||
};
|
||||
|
||||
struct _GChildWatchSource
|
||||
@ -281,6 +283,8 @@ static gint child_watch_wake_up_pipe[2] = {0, 0};
|
||||
G_LOCK_DEFINE_STATIC (main_context_list);
|
||||
static GSList *main_context_list = NULL;
|
||||
|
||||
static gint timer_perturb = -1;
|
||||
|
||||
GSourceFuncs g_timeout_funcs =
|
||||
{
|
||||
g_timeout_prepare,
|
||||
@ -3337,6 +3341,55 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source,
|
||||
timeout_source->expiration.tv_usec -= 1000000;
|
||||
timeout_source->expiration.tv_sec++;
|
||||
}
|
||||
if (timer_perturb==-1)
|
||||
{
|
||||
/*
|
||||
* we want a per machine/session unique 'random' value; try the dbus
|
||||
* address first, that has a UUID in it. If there is no dbus, use the
|
||||
* hostname for hashing.
|
||||
*/
|
||||
const char *session_bus_address = getenv("DBUS_SESSION_BUS_ADDRESS");
|
||||
if (!session_bus_address)
|
||||
session_bus_address = getenv("HOSTNAME");
|
||||
if (session_bus_address)
|
||||
timer_perturb = g_str_hash(session_bus_address);
|
||||
else
|
||||
timer_perturb = 0;
|
||||
}
|
||||
if (timeout_source->granularity)
|
||||
{
|
||||
gint remainder;
|
||||
gint gran; /* in usecs */
|
||||
gint perturb;
|
||||
|
||||
gran = timeout_source->granularity * 1000;
|
||||
perturb = timer_perturb % gran;
|
||||
/*
|
||||
* We want to give each machine a per machine pertubation;
|
||||
* shift time back first, and forward later after the rounding
|
||||
*/
|
||||
|
||||
timeout_source->expiration.tv_usec -= perturb;
|
||||
if (timeout_source->expiration.tv_usec < 0)
|
||||
{
|
||||
timeout_source->expiration.tv_usec += 1000000;
|
||||
timeout_source->expiration.tv_sec--;
|
||||
}
|
||||
|
||||
remainder = timeout_source->expiration.tv_usec % gran;
|
||||
if (remainder >= gran/4) /* round up */
|
||||
timeout_source->expiration.tv_usec += gran;
|
||||
timeout_source->expiration.tv_usec -= remainder;
|
||||
/* shift back */
|
||||
timeout_source->expiration.tv_usec += perturb;
|
||||
|
||||
/* the rounding may have overflown tv_usec */
|
||||
while (timeout_source->expiration.tv_usec > 1000000)
|
||||
{
|
||||
timeout_source->expiration.tv_usec -= 1000000;
|
||||
timeout_source->expiration.tv_sec++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
static gboolean
|
||||
@ -3459,6 +3512,39 @@ g_timeout_source_new (guint interval)
|
||||
return source;
|
||||
}
|
||||
|
||||
/**
|
||||
* g_timeout_source_new_seconds:
|
||||
* @interval: the timeout interval in seconds
|
||||
*
|
||||
* Creates a new timeout source.
|
||||
*
|
||||
* The source will not initially be associated with any #GMainContext
|
||||
* and must be added to one with g_source_attach() before it will be
|
||||
* executed.
|
||||
* The scheduling granularity/accuracy of this timeout source will be
|
||||
* in seconds.
|
||||
*
|
||||
* Return value: the newly-created timeout source
|
||||
*
|
||||
* Since: 2.14
|
||||
**/
|
||||
GSource *
|
||||
g_timeout_source_new_seconds (guint interval)
|
||||
{
|
||||
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
|
||||
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
||||
GTimeVal current_time;
|
||||
|
||||
timeout_source->interval = 1000*interval;
|
||||
timeout_source->granularity = 1000;
|
||||
|
||||
g_get_current_time (¤t_time);
|
||||
g_timeout_set_expiration (timeout_source, ¤t_time);
|
||||
|
||||
return source;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* g_timeout_add_full:
|
||||
* @priority: the priority of the idle source. Typically this will be in the
|
||||
@ -3526,10 +3612,15 @@ g_timeout_add_full (gint priority,
|
||||
* After each call to the timeout function, the time of the next
|
||||
* timeout is recalculated based on the current time and the given interval
|
||||
* (it does not try to 'catch up' time lost in delays).
|
||||
*
|
||||
*
|
||||
* If you want to have a timer in the "seconds" range and do not care
|
||||
* about the exact time of the first call of the timer, use the
|
||||
* g_timeout_add_seconds() function; this function allows for more
|
||||
* optimizations and more efficient system power usage.
|
||||
*
|
||||
* Return value: the ID (greater than 0) of the event source.
|
||||
**/
|
||||
guint
|
||||
guint
|
||||
g_timeout_add (guint32 interval,
|
||||
GSourceFunc function,
|
||||
gpointer data)
|
||||
@ -3538,6 +3629,62 @@ g_timeout_add (guint32 interval,
|
||||
interval, function, data, NULL);
|
||||
}
|
||||
|
||||
/**
|
||||
* g_timeout_add_seconds:
|
||||
* @interval: the time between calls to the function, in seconds
|
||||
* @function: function to call
|
||||
* @data: data to pass to @function
|
||||
*
|
||||
* Sets a function to be called at regular intervals, with the default
|
||||
* priority, #G_PRIORITY_DEFAULT. The function is called repeatedly
|
||||
* until it returns %FALSE, at which point the timeout is automatically
|
||||
* destroyed and the function will not be called again.
|
||||
*
|
||||
* Unlike g_timeout_add(), this function operates at whole second granularity.
|
||||
* The initial starting point of the timer is determined by the implementation
|
||||
* and the implementation is expected to group multiple timers together so that
|
||||
* they fire all at the same time.
|
||||
* To allow this grouping, the @interval to the first timer is rounded
|
||||
* and can deviate up to one second from the specified interval.
|
||||
* Subsequent timer iterations will generally run at the specified interval.
|
||||
*
|
||||
* Note that timeout functions may be delayed, due to the processing of other
|
||||
* event sources. Thus they should not be relied on for precise timing.
|
||||
* After each call to the timeout function, the time of the next
|
||||
* timeout is recalculated based on the current time and the given @interval
|
||||
*
|
||||
* If you want timing more precise than whole seconds, use g_timeout_add()
|
||||
* instead.
|
||||
*
|
||||
* The grouping of timers to fire at the same time results in a more power
|
||||
* and CPU efficient behavior so if your timer is in multiples of seconds
|
||||
* and you don't require the first timer exactly 1 second from now, the
|
||||
* use of g_timeout_add_second() is prefered over g_timeout_add().
|
||||
*
|
||||
* Return value: the ID (greater than 0) of the event source.
|
||||
*
|
||||
* Since: 2.14
|
||||
**/
|
||||
guint
|
||||
g_timeout_add_seconds (guint32 interval,
|
||||
GSourceFunc function,
|
||||
gpointer data)
|
||||
{
|
||||
GSource *source;
|
||||
guint id;
|
||||
|
||||
g_return_val_if_fail (function != NULL, 0);
|
||||
|
||||
source = g_timeout_source_new_seconds (interval);
|
||||
|
||||
g_source_set_callback (source, function, data, NULL);
|
||||
id = g_source_attach (source, NULL);
|
||||
g_source_unref (source);
|
||||
|
||||
return id;
|
||||
}
|
||||
|
||||
|
||||
/* Child watch functions */
|
||||
|
||||
#ifdef G_OS_WIN32
|
||||
|
@ -256,6 +256,7 @@ void g_source_get_current_time (GSource *source,
|
||||
GSource *g_idle_source_new (void);
|
||||
GSource *g_child_watch_source_new (GPid pid);
|
||||
GSource *g_timeout_source_new (guint interval);
|
||||
GSource *g_timeout_source_new_seconds (guint interval);
|
||||
|
||||
/* Miscellaneous functions
|
||||
*/
|
||||
@ -298,6 +299,9 @@ guint g_timeout_add_full (gint priority,
|
||||
guint g_timeout_add (guint interval,
|
||||
GSourceFunc function,
|
||||
gpointer data);
|
||||
guint g_timeout_add_seconds (guint interval,
|
||||
GSourceFunc function,
|
||||
gpointer data);
|
||||
guint g_child_watch_add_full (gint priority,
|
||||
GPid pid,
|
||||
GChildWatchFunc function,
|
||||
|
Loading…
Reference in New Issue
Block a user