diff options
author | Matthias Clasen <mclasen@redhat.com> | 2011-03-06 22:37:01 -0500 |
---|---|---|
committer | Matthias Clasen <mclasen@redhat.com> | 2011-03-06 22:39:10 -0500 |
commit | b0ec12ef7692ee95923e97451614e1049af3f0e1 (patch) | |
tree | e4f6154a73e0dc08696e0c1813b64c1a5533d229 | |
parent | 6416e01e11cc8805969417d6f1fb1b1014d9e9d6 (diff) |
Go back to the old logic in set_expiration
It was more complicated, but also more correct...
Also add a test to ensure that our rounding works as expected.
https://bugzilla.gnome.org/show_bug.cgi?id=643795
-rw-r--r-- | glib/gmain.c | 10 | ||||
-rw-r--r-- | glib/tests/timeout.c | 41 |
2 files changed, 48 insertions, 3 deletions
diff --git a/glib/gmain.c b/glib/gmain.c index 1af9a5c45..3a480f3a2 100644 --- a/glib/gmain.c +++ b/glib/gmain.c @@ -3801,6 +3801,7 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source, if (timeout_source->seconds) { + gint64 remainder; static gint timer_perturb = -1; if (timer_perturb == -1) @@ -3825,11 +3826,14 @@ g_timeout_set_expiration (GTimeoutSource *timeout_source, * always only *increase* the expiration time by adding a full * second in the case that the microsecond portion decreases. */ - if (timer_perturb < timeout_source->expiration % 1000000) + timeout_source->expiration -= timer_perturb; + + remainder = timeout_source->expiration % 1000000; + if (remainder >= 1000000/4) timeout_source->expiration += 1000000; - timeout_source->expiration = - ((timeout_source->expiration / 1000000) * 1000000) + timer_perturb; + timeout_source->expiration -= remainder; + timeout_source->expiration += timer_perturb; } } diff --git a/glib/tests/timeout.c b/glib/tests/timeout.c index ff33aa6a2..9354cd7a5 100644 --- a/glib/tests/timeout.c +++ b/glib/tests/timeout.c @@ -1,4 +1,5 @@ #include <glib.h> +#include <unistd.h> static GMainLoop *loop; @@ -42,12 +43,52 @@ test_seconds (void) g_main_loop_run (loop); } +static gint64 last_time; +static gint count; + +static gboolean +test_func (gpointer data) +{ + gint64 current_time; + + current_time = g_get_monotonic_time (); + + g_assert (current_time / 1000000 - last_time / 1000000 == 1); + + last_time = current_time; + count++; + + /* Make the timeout take up to 0.1 seconds. + * We should still get scheduled for the next second. + */ + usleep (count * 10000); + + if (count < 10) + return TRUE; + + g_main_loop_quit (loop); + + return FALSE; +} + +static void +test_rounding (void) +{ + loop = g_main_loop_new (NULL, FALSE); + + last_time = g_get_monotonic_time (); + g_timeout_add_seconds (1, test_func, NULL); + + g_main_loop_run (loop); +} + int main (int argc, char *argv[]) { g_test_init (&argc, &argv, NULL); g_test_add_func ("/timeout/seconds", test_seconds); + g_test_add_func ("/timeout/rounding", test_rounding); return g_test_run (); } |