summaryrefslogtreecommitdiffstats
path: root/adb/transport_local.cpp
diff options
context:
space:
mode:
authorYabin Cui <yabinc@google.com>2016-05-26 02:10:10 +0000
committerandroid-build-merger <android-build-merger@google.com>2016-05-26 02:10:10 +0000
commit16dad488b362d3812f9d67b4b751ba6cde22590d (patch)
tree814c161cfd93fc6115bd399f40cde7bdd0fc62d5 /adb/transport_local.cpp
parentd66e05c6c45698c69e3368090adfbd56c00fc9a8 (diff)
parentcfb0c5cd913b689c8f9d0d930c92c6a0804e2995 (diff)
downloadsystem_core-16dad488b362d3812f9d67b4b751ba6cde22590d.tar.gz
system_core-16dad488b362d3812f9d67b4b751ba6cde22590d.tar.bz2
system_core-16dad488b362d3812f9d67b4b751ba6cde22590d.zip
Merge "adb: retry connecting disconnected emulators instead of always looping." am: 50e91fec0e
am: cfb0c5cd91 * commit 'cfb0c5cd913b689c8f9d0d930c92c6a0804e2995': adb: retry connecting disconnected emulators instead of always looping. Change-Id: I4b7f30bd3738ce53eb343e5d0e20f3d20faf7e2a
Diffstat (limited to 'adb/transport_local.cpp')
-rw-r--r--adb/transport_local.cpp97
1 files changed, 84 insertions, 13 deletions
diff --git a/adb/transport_local.cpp b/adb/transport_local.cpp
index 63d36c083..fc197159c 100644
--- a/adb/transport_local.cpp
+++ b/adb/transport_local.cpp
@@ -17,6 +17,8 @@
#define TRACE_TAG TRANSPORT
#include "sysdeps.h"
+#include "sysdeps/condition_variable.h"
+#include "sysdeps/mutex.h"
#include "transport.h"
#include <errno.h>
@@ -25,6 +27,8 @@
#include <string.h>
#include <sys/types.h>
+#include <vector>
+
#include <android-base/stringprintf.h>
#include <cutils/sockets.h>
@@ -90,9 +94,9 @@ static int remote_write(apacket *p, atransport *t)
return 0;
}
-void local_connect(int port) {
+bool local_connect(int port) {
std::string dummy;
- local_connect_arbitrary_ports(port-1, port, &dummy);
+ return local_connect_arbitrary_ports(port-1, port, &dummy) == 0;
}
int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* error) {
@@ -126,18 +130,71 @@ int local_connect_arbitrary_ports(int console_port, int adb_port, std::string* e
}
#if ADB_HOST
+
+static void PollAllLocalPortsForEmulator() {
+ int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
+ int count = ADB_LOCAL_TRANSPORT_MAX;
+
+ // Try to connect to any number of running emulator instances.
+ for ( ; count > 0; count--, port += 2 ) {
+ local_connect(port);
+ }
+}
+
+// Retry the disconnected local port for 60 times, and sleep 1 second between two retries.
+constexpr uint32_t LOCAL_PORT_RETRY_COUNT = 60;
+constexpr uint32_t LOCAL_PORT_RETRY_INTERVAL_IN_MS = 1000;
+
+struct RetryPort {
+ int port;
+ uint32_t retry_count;
+};
+
+// Retry emulators just kicked.
+static std::vector<RetryPort>& retry_ports = *new std::vector<RetryPort>;
+std::mutex &retry_ports_lock = *new std::mutex;
+std::condition_variable &retry_ports_cond = *new std::condition_variable;
+
static void client_socket_thread(void* x) {
adb_thread_setname("client_socket_thread");
D("transport: client_socket_thread() starting");
+ PollAllLocalPortsForEmulator();
while (true) {
- int port = DEFAULT_ADB_LOCAL_TRANSPORT_PORT;
- int count = ADB_LOCAL_TRANSPORT_MAX;
+ std::vector<RetryPort> ports;
+ // Collect retry ports.
+ {
+ std::unique_lock<std::mutex> lock(retry_ports_lock);
+ while (retry_ports.empty()) {
+ retry_ports_cond.wait(lock);
+ }
+ retry_ports.swap(ports);
+ }
+ // Sleep here instead of the end of loop, because if we immediately try to reconnect
+ // the emulator just kicked, the adbd on the emulator may not have time to remove the
+ // just kicked transport.
+ adb_sleep_ms(LOCAL_PORT_RETRY_INTERVAL_IN_MS);
+
+ // Try connecting retry ports.
+ std::vector<RetryPort> next_ports;
+ for (auto& port : ports) {
+ VLOG(TRANSPORT) << "retry port " << port.port << ", last retry_count "
+ << port.retry_count;
+ if (local_connect(port.port)) {
+ VLOG(TRANSPORT) << "retry port " << port.port << " successfully";
+ continue;
+ }
+ if (--port.retry_count > 0) {
+ next_ports.push_back(port);
+ } else {
+ VLOG(TRANSPORT) << "stop retrying port " << port.port;
+ }
+ }
- // Try to connect to any number of running emulator instances.
- for ( ; count > 0; count--, port += 2 ) {
- local_connect(port);
+ // Copy back left retry ports.
+ {
+ std::unique_lock<std::mutex> lock(retry_ports_lock);
+ retry_ports.insert(retry_ports.end(), next_ports.begin(), next_ports.end());
}
- sleep(1);
}
}
@@ -346,17 +403,32 @@ static void remote_close(atransport *t)
t->sfd = -1;
adb_close(fd);
}
+#if ADB_HOST
+ int local_port;
+ if (t->GetLocalPortForEmulator(&local_port)) {
+ VLOG(TRANSPORT) << "remote_close, local_port = " << local_port;
+ std::unique_lock<std::mutex> lock(retry_ports_lock);
+ RetryPort port;
+ port.port = local_port;
+ port.retry_count = LOCAL_PORT_RETRY_COUNT;
+ retry_ports.push_back(port);
+ retry_ports_cond.notify_one();
+ }
+#endif
}
#if ADB_HOST
/* Only call this function if you already hold local_transports_lock. */
-atransport* find_emulator_transport_by_adb_port_locked(int adb_port)
+static atransport* find_emulator_transport_by_adb_port_locked(int adb_port)
{
int i;
for (i = 0; i < ADB_LOCAL_TRANSPORT_MAX; i++) {
- if (local_transports[i] && local_transports[i]->adb_port == adb_port) {
- return local_transports[i];
+ int local_port;
+ if (local_transports[i] && local_transports[i]->GetLocalPortForEmulator(&local_port)) {
+ if (local_port == adb_port) {
+ return local_transports[i];
+ }
}
}
return NULL;
@@ -403,13 +475,12 @@ int init_socket_transport(atransport *t, int s, int adb_port, int local)
t->sync_token = 1;
t->connection_state = kCsOffline;
t->type = kTransportLocal;
- t->adb_port = 0;
#if ADB_HOST
if (local) {
adb_mutex_lock( &local_transports_lock );
{
- t->adb_port = adb_port;
+ t->SetLocalPortForEmulator(adb_port);
atransport* existing_transport =
find_emulator_transport_by_adb_port_locked(adb_port);
int index = get_available_local_transport_index_locked();