diff options
author | Yabin Cui <yabinc@google.com> | 2016-05-26 02:10:10 +0000 |
---|---|---|
committer | android-build-merger <android-build-merger@google.com> | 2016-05-26 02:10:10 +0000 |
commit | 16dad488b362d3812f9d67b4b751ba6cde22590d (patch) | |
tree | 814c161cfd93fc6115bd399f40cde7bdd0fc62d5 /adb/transport_local.cpp | |
parent | d66e05c6c45698c69e3368090adfbd56c00fc9a8 (diff) | |
parent | cfb0c5cd913b689c8f9d0d930c92c6a0804e2995 (diff) | |
download | system_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.cpp | 97 |
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(); |