mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2024-12-26 15:36:14 +01:00
GTimeout: simplify math for 'seconds' case
The code was designed to deal with any granularity of timer and due to the use of GTimeVal/GTimeSpec, the math for this gets extremely confusing. From a practical standpoint, we only ever have a granularity of seconds. Take advantage of that fact in the code and vastly simplify the math.
This commit is contained in:
parent
b6854efdb9
commit
d9f5ab56c3
74
glib/gmain.c
74
glib/gmain.c
@ -290,7 +290,7 @@ struct _GTimeoutSource
|
|||||||
GSource source;
|
GSource source;
|
||||||
GTimeSpec expiration;
|
GTimeSpec expiration;
|
||||||
guint interval;
|
guint interval;
|
||||||
guint granularity;
|
gboolean seconds;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _GChildWatchSource
|
struct _GChildWatchSource
|
||||||
@ -393,8 +393,6 @@ static gint child_watch_wake_up_pipe[2] = {0, 0};
|
|||||||
G_LOCK_DEFINE_STATIC (main_context_list);
|
G_LOCK_DEFINE_STATIC (main_context_list);
|
||||||
static GSList *main_context_list = NULL;
|
static GSList *main_context_list = NULL;
|
||||||
|
|
||||||
static gint timer_perturb = -1;
|
|
||||||
|
|
||||||
GSourceFuncs g_timeout_funcs =
|
GSourceFuncs g_timeout_funcs =
|
||||||
{
|
{
|
||||||
g_timeout_prepare,
|
g_timeout_prepare,
|
||||||
@ -3575,54 +3573,36 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source,
|
|||||||
timeout_source->expiration.tv_nsec -= 1000000000;
|
timeout_source->expiration.tv_nsec -= 1000000000;
|
||||||
timeout_source->expiration.tv_sec++;
|
timeout_source->expiration.tv_sec++;
|
||||||
}
|
}
|
||||||
if (timer_perturb==-1)
|
if (timeout_source->seconds)
|
||||||
{
|
{
|
||||||
/*
|
static gint 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 = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
|
|
||||||
if (!session_bus_address)
|
|
||||||
session_bus_address = g_getenv ("HOSTNAME");
|
|
||||||
if (session_bus_address)
|
|
||||||
timer_perturb = ABS ((gint) g_str_hash (session_bus_address));
|
|
||||||
else
|
|
||||||
timer_perturb = 0;
|
|
||||||
}
|
|
||||||
if (timeout_source->granularity)
|
|
||||||
{
|
|
||||||
gint remainder;
|
|
||||||
gint gran; /* in nsecs */
|
|
||||||
gint perturb;
|
|
||||||
|
|
||||||
gran = timeout_source->granularity * 1000000;
|
if (timer_perturb == -1)
|
||||||
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_nsec -= perturb;
|
|
||||||
if (timeout_source->expiration.tv_nsec < 0)
|
|
||||||
{
|
{
|
||||||
timeout_source->expiration.tv_nsec += 1000000000;
|
/*
|
||||||
timeout_source->expiration.tv_sec--;
|
* 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 = g_getenv ("DBUS_SESSION_BUS_ADDRESS");
|
||||||
|
if (!session_bus_address)
|
||||||
|
session_bus_address = g_getenv ("HOSTNAME");
|
||||||
|
if (session_bus_address)
|
||||||
|
timer_perturb = ABS ((gint) g_str_hash (session_bus_address)) % 1000000;
|
||||||
|
else
|
||||||
|
timer_perturb = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
remainder = timeout_source->expiration.tv_nsec % gran;
|
/* We want the microseconds part of the timeout to land on the
|
||||||
if (remainder >= gran/4) /* round up */
|
* 'timer_perturb' mark, but we need to make sure we don't try to
|
||||||
timeout_source->expiration.tv_nsec += gran;
|
* set the timeout in the past. We do this by ensuring that we
|
||||||
timeout_source->expiration.tv_nsec -= remainder;
|
* always only *increase* the expiration time by adding a full
|
||||||
/* shift back */
|
* second in the case that the microsecond portion decreases.
|
||||||
timeout_source->expiration.tv_nsec += perturb;
|
*/
|
||||||
|
if (timer_perturb * 1000 < timeout_source->expiration.tv_nsec)
|
||||||
|
timeout_source->expiration.tv_sec++;
|
||||||
|
|
||||||
/* the rounding may have overflown tv_nsec */
|
timeout_source->expiration.tv_nsec = timer_perturb * 1000;
|
||||||
while (timeout_source->expiration.tv_nsec > 1000000000)
|
|
||||||
{
|
|
||||||
timeout_source->expiration.tv_nsec -= 1000000000;
|
|
||||||
timeout_source->expiration.tv_sec++;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -3770,8 +3750,8 @@ g_timeout_source_new_seconds (guint interval)
|
|||||||
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
||||||
GTimeSpec now;
|
GTimeSpec now;
|
||||||
|
|
||||||
timeout_source->interval = 1000*interval;
|
timeout_source->interval = 1000 * interval;
|
||||||
timeout_source->granularity = 1000;
|
timeout_source->seconds = TRUE;
|
||||||
|
|
||||||
g_get_monotonic_time (&now);
|
g_get_monotonic_time (&now);
|
||||||
g_timeout_set_expiration (timeout_source, &now);
|
g_timeout_set_expiration (timeout_source, &now);
|
||||||
|
Loading…
Reference in New Issue
Block a user