summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJosh Gao2018-07-31 16:12:59 -0500
committerJosh Gao2018-07-31 17:57:49 -0500
commite445a6d8a23d456c0720c92bc7b31ce033bfc345 (patch)
tree8613acc4ff5bfbdf60d719ba62a77976d12c5f54
parent95af641bd65f6f02318ebc66bf5faaeb370108c8 (diff)
downloadplatform-system-core-e445a6d8a23d456c0720c92bc7b31ce033bfc345.tar.gz
platform-system-core-e445a6d8a23d456c0720c92bc7b31ce033bfc345.tar.xz
platform-system-core-e445a6d8a23d456c0720c92bc7b31ce033bfc345.zip
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
-rw-r--r--adb/transport.cpp26
1 files 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 @@
50#include "adb_trace.h" 50#include "adb_trace.h"
51#include "adb_utils.h" 51#include "adb_utils.h"
52#include "fdevent.h" 52#include "fdevent.h"
53#include "sysdeps/chrono.h"
53 54
54static void register_transport(atransport* transport); 55static void register_transport(atransport* transport);
55static void remove_transport(atransport* transport); 56static void remove_transport(atransport* transport);
@@ -104,10 +105,16 @@ class ReconnectHandler {
104 atransport* transport; 105 atransport* transport;
105 std::chrono::steady_clock::time_point reconnect_time; 106 std::chrono::steady_clock::time_point reconnect_time;
106 size_t attempts_left; 107 size_t attempts_left;
108
109 bool operator<(const ReconnectAttempt& rhs) const {
110 // std::priority_queue returns the largest element first, so we want attempts that have
111 // less time remaining (i.e. smaller time_points) to compare greater.
112 return reconnect_time > rhs.reconnect_time;
113 }
107 }; 114 };
108 115
109 // Only retry for up to one minute. 116 // Only retry for up to one minute.
110 static constexpr const std::chrono::seconds kDefaultTimeout = std::chrono::seconds(10); 117 static constexpr const std::chrono::seconds kDefaultTimeout = 10s;
111 static constexpr const size_t kMaxAttempts = 6; 118 static constexpr const size_t kMaxAttempts = 6;
112 119
113 // Protects all members. 120 // Protects all members.
@@ -115,7 +122,7 @@ class ReconnectHandler {
115 bool running_ GUARDED_BY(reconnect_mutex_) = true; 122 bool running_ GUARDED_BY(reconnect_mutex_) = true;
116 std::thread handler_thread_; 123 std::thread handler_thread_;
117 std::condition_variable reconnect_cv_; 124 std::condition_variable reconnect_cv_;
118 std::queue<ReconnectAttempt> reconnect_queue_ GUARDED_BY(reconnect_mutex_); 125 std::priority_queue<ReconnectAttempt> reconnect_queue_ GUARDED_BY(reconnect_mutex_);
119 126
120 DISALLOW_COPY_AND_ASSIGN(ReconnectHandler); 127 DISALLOW_COPY_AND_ASSIGN(ReconnectHandler);
121}; 128};
@@ -137,7 +144,7 @@ void ReconnectHandler::Stop() {
137 // Drain the queue to free all resources. 144 // Drain the queue to free all resources.
138 std::lock_guard<std::mutex> lock(reconnect_mutex_); 145 std::lock_guard<std::mutex> lock(reconnect_mutex_);
139 while (!reconnect_queue_.empty()) { 146 while (!reconnect_queue_.empty()) {
140 ReconnectAttempt attempt = reconnect_queue_.front(); 147 ReconnectAttempt attempt = reconnect_queue_.top();
141 reconnect_queue_.pop(); 148 reconnect_queue_.pop();
142 remove_transport(attempt.transport); 149 remove_transport(attempt.transport);
143 } 150 }
@@ -148,9 +155,10 @@ void ReconnectHandler::TrackTransport(atransport* transport) {
148 { 155 {
149 std::lock_guard<std::mutex> lock(reconnect_mutex_); 156 std::lock_guard<std::mutex> lock(reconnect_mutex_);
150 if (!running_) return; 157 if (!running_) return;
151 reconnect_queue_.emplace(ReconnectAttempt{ 158 // Arbitrary sleep to give adbd time to get ready, if we disconnected because it exited.
152 transport, std::chrono::steady_clock::now() + ReconnectHandler::kDefaultTimeout, 159 auto reconnect_time = std::chrono::steady_clock::now() + 250ms;
153 ReconnectHandler::kMaxAttempts}); 160 reconnect_queue_.emplace(
161 ReconnectAttempt{transport, reconnect_time, ReconnectHandler::kMaxAttempts});
154 } 162 }
155 reconnect_cv_.notify_one(); 163 reconnect_cv_.notify_one();
156} 164}
@@ -167,7 +175,7 @@ void ReconnectHandler::Run() {
167 // system_clock as its clock, so we're probably hosed if the clock changes, 175 // system_clock as its clock, so we're probably hosed if the clock changes,
168 // even if we use steady_clock throughout. This problem goes away once we 176 // even if we use steady_clock throughout. This problem goes away once we
169 // switch to libc++. 177 // switch to libc++.
170 reconnect_cv_.wait_until(lock, reconnect_queue_.front().reconnect_time); 178 reconnect_cv_.wait_until(lock, reconnect_queue_.top().reconnect_time);
171 } else { 179 } else {
172 reconnect_cv_.wait(lock); 180 reconnect_cv_.wait(lock);
173 } 181 }
@@ -178,11 +186,11 @@ void ReconnectHandler::Run() {
178 // Go back to sleep in case |reconnect_cv_| woke up spuriously and we still 186 // Go back to sleep in case |reconnect_cv_| woke up spuriously and we still
179 // have more time to wait for the current attempt. 187 // have more time to wait for the current attempt.
180 auto now = std::chrono::steady_clock::now(); 188 auto now = std::chrono::steady_clock::now();
181 if (reconnect_queue_.front().reconnect_time > now) { 189 if (reconnect_queue_.top().reconnect_time > now) {
182 continue; 190 continue;
183 } 191 }
184 192
185 attempt = reconnect_queue_.front(); 193 attempt = reconnect_queue_.top();
186 reconnect_queue_.pop(); 194 reconnect_queue_.pop();
187 if (attempt.transport->kicked()) { 195 if (attempt.transport->kicked()) {
188 D("transport %s was kicked. giving up on it.", attempt.transport->serial.c_str()); 196 D("transport %s was kicked. giving up on it.", attempt.transport->serial.c_str());