From e445a6d8a23d456c0720c92bc7b31ce033bfc345 Mon Sep 17 00:00:00 2001 From: Josh Gao Date: Tue, 31 Jul 2018 14:12:59 -0700 Subject: adb: more immediately try to reconnect connections. Most disconnects we're likely to encounter are cases where either we notice immediately and can start reconnecting almost immediately (adbd restarting because of `adb root`, etc.), or where we won't notice for a while anyway, so a 10 second sleep is somewhat meaningless. Test: adb root; time adb wait-for-device shell Change-Id: I18e9213dc4e84d735e9240118a368dcb38f21c78 --- adb/transport.cpp | 26 +++++++++++++++++--------- 1 file changed, 17 insertions(+), 9 deletions(-) diff --git a/adb/transport.cpp b/adb/transport.cpp index b08c7f9bb..b45c43f89 100644 --- a/adb/transport.cpp +++ b/adb/transport.cpp @@ -50,6 +50,7 @@ #include "adb_trace.h" #include "adb_utils.h" #include "fdevent.h" +#include "sysdeps/chrono.h" static void register_transport(atransport* transport); static void remove_transport(atransport* transport); @@ -104,10 +105,16 @@ class ReconnectHandler { atransport* transport; std::chrono::steady_clock::time_point reconnect_time; size_t attempts_left; + + bool operator<(const ReconnectAttempt& rhs) const { + // std::priority_queue returns the largest element first, so we want attempts that have + // less time remaining (i.e. smaller time_points) to compare greater. + return reconnect_time > rhs.reconnect_time; + } }; // Only retry for up to one minute. - static constexpr const std::chrono::seconds kDefaultTimeout = std::chrono::seconds(10); + static constexpr const std::chrono::seconds kDefaultTimeout = 10s; static constexpr const size_t kMaxAttempts = 6; // Protects all members. @@ -115,7 +122,7 @@ class ReconnectHandler { bool running_ GUARDED_BY(reconnect_mutex_) = true; std::thread handler_thread_; std::condition_variable reconnect_cv_; - std::queue reconnect_queue_ GUARDED_BY(reconnect_mutex_); + std::priority_queue reconnect_queue_ GUARDED_BY(reconnect_mutex_); DISALLOW_COPY_AND_ASSIGN(ReconnectHandler); }; @@ -137,7 +144,7 @@ void ReconnectHandler::Stop() { // Drain the queue to free all resources. std::lock_guard lock(reconnect_mutex_); while (!reconnect_queue_.empty()) { - ReconnectAttempt attempt = reconnect_queue_.front(); + ReconnectAttempt attempt = reconnect_queue_.top(); reconnect_queue_.pop(); remove_transport(attempt.transport); } @@ -148,9 +155,10 @@ void ReconnectHandler::TrackTransport(atransport* transport) { { std::lock_guard lock(reconnect_mutex_); if (!running_) return; - reconnect_queue_.emplace(ReconnectAttempt{ - transport, std::chrono::steady_clock::now() + ReconnectHandler::kDefaultTimeout, - ReconnectHandler::kMaxAttempts}); + // Arbitrary sleep to give adbd time to get ready, if we disconnected because it exited. + auto reconnect_time = std::chrono::steady_clock::now() + 250ms; + reconnect_queue_.emplace( + ReconnectAttempt{transport, reconnect_time, ReconnectHandler::kMaxAttempts}); } reconnect_cv_.notify_one(); } @@ -167,7 +175,7 @@ void ReconnectHandler::Run() { // system_clock as its clock, so we're probably hosed if the clock changes, // even if we use steady_clock throughout. This problem goes away once we // switch to libc++. - reconnect_cv_.wait_until(lock, reconnect_queue_.front().reconnect_time); + reconnect_cv_.wait_until(lock, reconnect_queue_.top().reconnect_time); } else { reconnect_cv_.wait(lock); } @@ -178,11 +186,11 @@ void ReconnectHandler::Run() { // Go back to sleep in case |reconnect_cv_| woke up spuriously and we still // have more time to wait for the current attempt. auto now = std::chrono::steady_clock::now(); - if (reconnect_queue_.front().reconnect_time > now) { + if (reconnect_queue_.top().reconnect_time > now) { continue; } - attempt = reconnect_queue_.front(); + attempt = reconnect_queue_.top(); reconnect_queue_.pop(); if (attempt.transport->kicked()) { D("transport %s was kicked. giving up on it.", attempt.transport->serial.c_str()); -- cgit v1.2.3-54-g00ecf