diff options
author | Josh Gao | 2018-07-31 16:12:59 -0500 |
---|---|---|
committer | Josh Gao | 2018-07-31 17:57:49 -0500 |
commit | e445a6d8a23d456c0720c92bc7b31ce033bfc345 (patch) | |
tree | 8613acc4ff5bfbdf60d719ba62a77976d12c5f54 | |
parent | 95af641bd65f6f02318ebc66bf5faaeb370108c8 (diff) | |
download | platform-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.cpp | 26 |
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 | ||
54 | static void register_transport(atransport* transport); | 55 | static void register_transport(atransport* transport); |
55 | static void remove_transport(atransport* transport); | 56 | static 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()); |