]> git.ipfire.org Git - thirdparty/dbus.git/commitdiff
Fix issue where timeouts can overflow.
authorScott James Remnant <scott@ubuntu.com>
Mon, 11 May 2009 21:41:49 +0000 (22:41 +0100)
committerColin Walters <walters@verbum.org>
Tue, 14 Jul 2009 19:37:53 +0000 (15:37 -0400)
* dbus/dbus-connection.c (_dbus_connection_block_pending_call): Rework
  the timeout math so instead of calculating an end time, which may
  overflow, we instead calculate the elapsed time which is always
  smaller than the boundaries.

Signed-off-by: Scott James Remnant <scott@ubuntu.com>
(cherry picked from commit 1faa92114f6489d286ad4cebe5e91b2145a4f7d1)

dbus/dbus-connection.c

index 31a1d99dad5ed7e1f95f71fa7b5477183d2a6ee3..d18cad614b5b624388537b9ebc3b90cfe3765b30 100644 (file)
@@ -2275,13 +2275,12 @@ void
 _dbus_connection_block_pending_call (DBusPendingCall *pending)
 {
   long start_tv_sec, start_tv_usec;
-  long end_tv_sec, end_tv_usec;
   long tv_sec, tv_usec;
   DBusDispatchStatus status;
   DBusConnection *connection;
   dbus_uint32_t client_serial;
   DBusTimeout *timeout;
-  int timeout_milliseconds;
+  int timeout_milliseconds, elapsed_milliseconds;
 
   _dbus_assert (pending != NULL);
 
@@ -2305,18 +2304,12 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
   if (timeout)
     {
       timeout_milliseconds = dbus_timeout_get_interval (timeout);
-      
       _dbus_get_current_time (&start_tv_sec, &start_tv_usec);
-      end_tv_sec = start_tv_sec + timeout_milliseconds / 1000;
-      end_tv_usec = start_tv_usec + (timeout_milliseconds % 1000) * 1000;
-      end_tv_sec += end_tv_usec / _DBUS_USEC_PER_SECOND;
-      end_tv_usec = end_tv_usec % _DBUS_USEC_PER_SECOND;
 
-      _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec to %ld sec %ld usec\n",
+      _dbus_verbose ("dbus_connection_send_with_reply_and_block(): will block %d milliseconds for reply serial %u from %ld sec %ld usec\n",
                      timeout_milliseconds,
                      client_serial,
-                     start_tv_sec, start_tv_usec,
-                     end_tv_sec, end_tv_usec);
+                     start_tv_sec, start_tv_usec);
     }
   else
     {
@@ -2365,6 +2358,8 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
     }
   
   _dbus_get_current_time (&tv_sec, &tv_usec);
+  elapsed_milliseconds = (tv_sec - start_tv_sec) * 1000 +
+         (tv_usec - start_tv_usec) / 1000;
   
   if (!_dbus_connection_get_is_connected_unlocked (connection))
     {
@@ -2406,11 +2401,9 @@ _dbus_connection_block_pending_call (DBusPendingCall *pending)
     }
   else if (tv_sec < start_tv_sec)
     _dbus_verbose ("dbus_connection_send_with_reply_and_block(): clock set backward\n");
-  else if (tv_sec < end_tv_sec ||
-           (tv_sec == end_tv_sec && tv_usec < end_tv_usec))
+  else if (elapsed_milliseconds < timeout_milliseconds)
     {
-      timeout_milliseconds = (end_tv_sec - tv_sec) * 1000 +
-        (end_tv_usec - tv_usec) / 1000;
+      timeout_milliseconds -= elapsed_milliseconds;
       _dbus_verbose ("dbus_connection_send_with_reply_and_block(): %d milliseconds remain\n", timeout_milliseconds);
       _dbus_assert (timeout_milliseconds >= 0);