mirror of
https://gitlab.gnome.org/GNOME/glib.git
synced 2025-02-05 10:38:08 +01:00
switch GTimeoutSource to use monotonic time
This commit is contained in:
parent
b7d8363fbe
commit
91113a8aee
72
glib/gmain.c
72
glib/gmain.c
@ -288,7 +288,7 @@ struct _GMainLoop
|
|||||||
struct _GTimeoutSource
|
struct _GTimeoutSource
|
||||||
{
|
{
|
||||||
GSource source;
|
GSource source;
|
||||||
GTimeVal expiration;
|
GTimeSpec expiration;
|
||||||
guint interval;
|
guint interval;
|
||||||
guint granularity;
|
guint granularity;
|
||||||
};
|
};
|
||||||
@ -3561,16 +3561,16 @@ g_main_context_is_owner (GMainContext *context)
|
|||||||
|
|
||||||
static void
|
static void
|
||||||
g_timeout_set_expiration (GTimeoutSource *timeout_source,
|
g_timeout_set_expiration (GTimeoutSource *timeout_source,
|
||||||
GTimeVal *current_time)
|
GTimeSpec *current_time)
|
||||||
{
|
{
|
||||||
guint seconds = timeout_source->interval / 1000;
|
guint seconds = timeout_source->interval / 1000;
|
||||||
guint msecs = timeout_source->interval - seconds * 1000;
|
guint msecs = timeout_source->interval - seconds * 1000;
|
||||||
|
|
||||||
timeout_source->expiration.tv_sec = current_time->tv_sec + seconds;
|
timeout_source->expiration.tv_sec = current_time->tv_sec + seconds;
|
||||||
timeout_source->expiration.tv_usec = current_time->tv_usec + msecs * 1000;
|
timeout_source->expiration.tv_nsec = current_time->tv_nsec + msecs * 1000000;
|
||||||
if (timeout_source->expiration.tv_usec >= 1000000)
|
if (timeout_source->expiration.tv_nsec >= 1000000000)
|
||||||
{
|
{
|
||||||
timeout_source->expiration.tv_usec -= 1000000;
|
timeout_source->expiration.tv_nsec -= 1000000000;
|
||||||
timeout_source->expiration.tv_sec++;
|
timeout_source->expiration.tv_sec++;
|
||||||
}
|
}
|
||||||
if (timer_perturb==-1)
|
if (timer_perturb==-1)
|
||||||
@ -3591,34 +3591,34 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source,
|
|||||||
if (timeout_source->granularity)
|
if (timeout_source->granularity)
|
||||||
{
|
{
|
||||||
gint remainder;
|
gint remainder;
|
||||||
gint gran; /* in usecs */
|
gint gran; /* in nsecs */
|
||||||
gint perturb;
|
gint perturb;
|
||||||
|
|
||||||
gran = timeout_source->granularity * 1000;
|
gran = timeout_source->granularity * 1000000;
|
||||||
perturb = timer_perturb % gran;
|
perturb = timer_perturb % gran;
|
||||||
/*
|
/*
|
||||||
* We want to give each machine a per machine pertubation;
|
* We want to give each machine a per machine pertubation;
|
||||||
* shift time back first, and forward later after the rounding
|
* shift time back first, and forward later after the rounding
|
||||||
*/
|
*/
|
||||||
|
|
||||||
timeout_source->expiration.tv_usec -= perturb;
|
timeout_source->expiration.tv_nsec -= perturb;
|
||||||
if (timeout_source->expiration.tv_usec < 0)
|
if (timeout_source->expiration.tv_nsec < 0)
|
||||||
{
|
{
|
||||||
timeout_source->expiration.tv_usec += 1000000;
|
timeout_source->expiration.tv_nsec += 1000000000;
|
||||||
timeout_source->expiration.tv_sec--;
|
timeout_source->expiration.tv_sec--;
|
||||||
}
|
}
|
||||||
|
|
||||||
remainder = timeout_source->expiration.tv_usec % gran;
|
remainder = timeout_source->expiration.tv_nsec % gran;
|
||||||
if (remainder >= gran/4) /* round up */
|
if (remainder >= gran/4) /* round up */
|
||||||
timeout_source->expiration.tv_usec += gran;
|
timeout_source->expiration.tv_nsec += gran;
|
||||||
timeout_source->expiration.tv_usec -= remainder;
|
timeout_source->expiration.tv_nsec -= remainder;
|
||||||
/* shift back */
|
/* shift back */
|
||||||
timeout_source->expiration.tv_usec += perturb;
|
timeout_source->expiration.tv_nsec += perturb;
|
||||||
|
|
||||||
/* the rounding may have overflown tv_usec */
|
/* the rounding may have overflown tv_nsec */
|
||||||
while (timeout_source->expiration.tv_usec > 1000000)
|
while (timeout_source->expiration.tv_nsec > 1000000000)
|
||||||
{
|
{
|
||||||
timeout_source->expiration.tv_usec -= 1000000;
|
timeout_source->expiration.tv_nsec -= 1000000000;
|
||||||
timeout_source->expiration.tv_sec++;
|
timeout_source->expiration.tv_sec++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3630,14 +3630,14 @@ g_timeout_prepare (GSource *source,
|
|||||||
{
|
{
|
||||||
glong sec;
|
glong sec;
|
||||||
glong msec;
|
glong msec;
|
||||||
GTimeVal current_time;
|
GTimeSpec now;
|
||||||
|
|
||||||
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
||||||
|
|
||||||
g_source_get_current_time (source, ¤t_time);
|
g_source_get_time (source, &now);
|
||||||
|
|
||||||
sec = timeout_source->expiration.tv_sec - current_time.tv_sec;
|
sec = timeout_source->expiration.tv_sec - now.tv_sec;
|
||||||
msec = (timeout_source->expiration.tv_usec - current_time.tv_usec) / 1000;
|
msec = (timeout_source->expiration.tv_nsec - now.tv_nsec) / 1000000;
|
||||||
|
|
||||||
/* We do the following in a rather convoluted fashion to deal with
|
/* We do the following in a rather convoluted fashion to deal with
|
||||||
* the fact that we don't have an integral type big enough to hold
|
* the fact that we don't have an integral type big enough to hold
|
||||||
@ -3663,7 +3663,7 @@ g_timeout_prepare (GSource *source,
|
|||||||
* reset the expiration time to now + timeout_source->interval;
|
* reset the expiration time to now + timeout_source->interval;
|
||||||
* this at least avoids hanging for long periods of time.
|
* this at least avoids hanging for long periods of time.
|
||||||
*/
|
*/
|
||||||
g_timeout_set_expiration (timeout_source, ¤t_time);
|
g_timeout_set_expiration (timeout_source, &now);
|
||||||
msec = MIN (G_MAXINT, timeout_source->interval);
|
msec = MIN (G_MAXINT, timeout_source->interval);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@ -3680,14 +3680,14 @@ g_timeout_prepare (GSource *source,
|
|||||||
static gboolean
|
static gboolean
|
||||||
g_timeout_check (GSource *source)
|
g_timeout_check (GSource *source)
|
||||||
{
|
{
|
||||||
GTimeVal current_time;
|
GTimeSpec now;
|
||||||
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
||||||
|
|
||||||
g_source_get_current_time (source, ¤t_time);
|
g_source_get_time (source, &now);
|
||||||
|
|
||||||
return ((timeout_source->expiration.tv_sec < current_time.tv_sec) ||
|
return ((timeout_source->expiration.tv_sec < now.tv_sec) ||
|
||||||
((timeout_source->expiration.tv_sec == current_time.tv_sec) &&
|
((timeout_source->expiration.tv_sec == now.tv_sec) &&
|
||||||
(timeout_source->expiration.tv_usec <= current_time.tv_usec)));
|
(timeout_source->expiration.tv_nsec <= now.tv_nsec)));
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -3706,10 +3706,10 @@ g_timeout_dispatch (GSource *source,
|
|||||||
|
|
||||||
if (callback (user_data))
|
if (callback (user_data))
|
||||||
{
|
{
|
||||||
GTimeVal current_time;
|
GTimeSpec now;
|
||||||
|
|
||||||
g_source_get_current_time (source, ¤t_time);
|
g_source_get_time (source, &now);
|
||||||
g_timeout_set_expiration (timeout_source, ¤t_time);
|
g_timeout_set_expiration (timeout_source, &now);
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -3734,12 +3734,12 @@ g_timeout_source_new (guint interval)
|
|||||||
{
|
{
|
||||||
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
|
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
|
||||||
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
||||||
GTimeVal current_time;
|
GTimeSpec now;
|
||||||
|
|
||||||
timeout_source->interval = interval;
|
timeout_source->interval = interval;
|
||||||
|
|
||||||
g_get_current_time (¤t_time);
|
g_get_monotonic_time (&now);
|
||||||
g_timeout_set_expiration (timeout_source, ¤t_time);
|
g_timeout_set_expiration (timeout_source, &now);
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
@ -3766,13 +3766,13 @@ g_timeout_source_new_seconds (guint interval)
|
|||||||
{
|
{
|
||||||
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
|
GSource *source = g_source_new (&g_timeout_funcs, sizeof (GTimeoutSource));
|
||||||
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
GTimeoutSource *timeout_source = (GTimeoutSource *)source;
|
||||||
GTimeVal current_time;
|
GTimeSpec now;
|
||||||
|
|
||||||
timeout_source->interval = 1000*interval;
|
timeout_source->interval = 1000*interval;
|
||||||
timeout_source->granularity = 1000;
|
timeout_source->granularity = 1000;
|
||||||
|
|
||||||
g_get_current_time (¤t_time);
|
g_get_monotonic_time (&now);
|
||||||
g_timeout_set_expiration (timeout_source, ¤t_time);
|
g_timeout_set_expiration (timeout_source, &now);
|
||||||
|
|
||||||
return source;
|
return source;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user