gasyncqueue: fix a 32bit overflow in g_async_queue_timed_pop
authorDan Winship <danw@gnome.org>
Wed, 22 Feb 2012 13:12:52 +0000 (08:12 -0500)
committerDan Winship <danw@gnome.org>
Wed, 22 Feb 2012 16:36:08 +0000 (11:36 -0500)
also, add a test for g_async_queue_timed_pop() and
g_async_queue_timeout_pop() to tests/asyncqueue.c

https://bugzilla.gnome.org/show_bug.cgi?id=669670

glib/gasyncqueue.c
glib/tests/asyncqueue.c

index dab487c..31976bc 100644 (file)
@@ -602,7 +602,7 @@ g_async_queue_timed_pop (GAsyncQueue *queue,
   if (end_time != NULL)
     {
       m_end_time = g_get_monotonic_time () +
-       (end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec -
+       ((gint64)end_time->tv_sec * G_USEC_PER_SEC + end_time->tv_usec -
         g_get_real_time ());
     }
   else
index ce10646..21b672f 100644 (file)
@@ -169,6 +169,40 @@ test_async_queue_threads (void)
   g_assert_cmpint (c, ==, 1000);
 }
 
+static void
+test_async_queue_timed (void)
+{
+  GAsyncQueue *q;
+  GTimeVal tv;
+  gint64 start, end, diff;
+  gpointer val;
+
+  q = g_async_queue_new ();
+
+  start = g_get_monotonic_time ();
+  val = g_async_queue_timeout_pop (q, G_USEC_PER_SEC / 10);
+  g_assert (val == NULL);
+
+  end = g_get_monotonic_time ();
+  diff = end - start;
+  g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
+  /* diff should be only a little bit more than G_USEC_PER_SEC/10, but
+   * we have to leave some wiggle room for heavily-loaded machines...
+   */
+  g_assert_cmpint (diff, <, G_USEC_PER_SEC);
+
+  start = end;
+  g_get_current_time (&tv);
+  g_time_val_add (&tv, G_USEC_PER_SEC / 10);
+  val = g_async_queue_timed_pop (q, &tv);
+  g_assert (val == NULL);
+
+  end = g_get_monotonic_time ();
+  diff = end - start;
+  g_assert_cmpint (diff, >=, G_USEC_PER_SEC / 10);
+  g_assert_cmpint (diff, <, G_USEC_PER_SEC);
+}
+
 int
 main (int argc, char *argv[])
 {
@@ -177,6 +211,7 @@ main (int argc, char *argv[])
   g_test_add_func ("/asyncqueue/sort", test_async_queue_sort);
   g_test_add_func ("/asyncqueue/destroy", test_async_queue_destroy);
   g_test_add_func ("/asyncqueue/threads", test_async_queue_threads);
+  g_test_add_func ("/asyncqueue/timed", test_async_queue_timed);
 
   return g_test_run ();
 }