summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2011-03-06 22:37:01 -0500
committerMatthias Clasen <mclasen@redhat.com>2011-03-06 22:39:10 -0500
commitb0ec12ef7692ee95923e97451614e1049af3f0e1 (patch)
treee4f6154a73e0dc08696e0c1813b64c1a5533d229
parent6416e01e11cc8805969417d6f1fb1b1014d9e9d6 (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.c10
-rw-r--r--glib/tests/timeout.c41
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 ();
}