From 3e414c46b31eb1e6e0140d62be04ea5f7d64e12a Mon Sep 17 00:00:00 2001 From: John Hood Date: Fri, 28 Oct 2016 01:59:24 -0400 Subject: [PATCH] Update send/ack timers on empty diff The root problem here is that writes to the frame buffer may alter it, but leave it with the same contents as before, and the diff between the two states is the empty string. With the dirty-rows, smart-pointer changes to Framebuffer, it is easy to run into this situation. This got Network::TransportSender confused about timeouts, and mosh-server would spin. The theoretically correct fix would be to have operator==() exactly correspond to diff(otherstate).empty(). I have partly implemented this (and may yet finish) but it's not trivial to get right. This is a much simpler fix that simply attempts to correctly update timers when two framebuffers are different and an empty diff is generated. --- src/network/transportsender-impl.h | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/src/network/transportsender-impl.h b/src/network/transportsender-impl.h index 328bf10..e9e4b6d 100644 --- a/src/network/transportsender-impl.h +++ b/src/network/transportsender-impl.h @@ -187,11 +187,16 @@ void TransportSender::tick( void ) } } - if ( diff.empty() && (now >= next_ack_time) ) { - send_empty_ack(); - mindelay_clock = uint64_t( -1 ); - } else if ( !diff.empty() && ( (now >= next_send_time) - || (now >= next_ack_time) ) ) { + if ( diff.empty() ) { + if ( (now >= next_ack_time) ) { + send_empty_ack(); + mindelay_clock = uint64_t( -1 ); + } + if ( (now >= next_send_time) ) { + next_send_time = uint64_t( -1 ); + mindelay_clock = uint64_t( -1 ); + } + } else if ( (now >= next_send_time) || (now >= next_ack_time) ) { /* Send diffs or ack */ send_to_receiver( diff ); mindelay_clock = uint64_t( -1 );