summaryrefslogtreecommitdiffstats
path: root/adb
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2019-03-26 18:47:45 -0700
committerJosh Gao <jmgao@google.com>2019-03-27 18:04:45 +0000
commit19dc2963057bda67f30adcfe1bf70b533f7310ca (patch)
tree2ee00b986cbd13feaaa5b35f4f0d158f6c595194 /adb
parent10533c57ed6b3727d504f1936669f0035f1f9de4 (diff)
downloadsystem_core-19dc2963057bda67f30adcfe1bf70b533f7310ca.tar.gz
system_core-19dc2963057bda67f30adcfe1bf70b533f7310ca.tar.bz2
system_core-19dc2963057bda67f30adcfe1bf70b533f7310ca.zip
adbd: wait for FUNCTIONFS_BIND for up to a second, then retry.
Occasionally, after we open the functionfs endpoint and write our descriptors to it, we end up in a state where we never receive any events from ep0, presumably due to a race against some other part of the system, since adding sleeps reduces the likelihood. Add an (arbitrarily chosen) timeout for the initial FUNCTIONFS_BIND we read, and retry on failure. Bug: http://b/128679787 Test: unplug and replug a blueline 14,000 times with a usb switch board Change-Id: I4b3d5d552179ee7f3fefcc15f9575f793926f784
Diffstat (limited to 'adb')
-rw-r--r--adb/daemon/usb.cpp25
1 files changed, 19 insertions, 6 deletions
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index 8a5000336..14cdb6961 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -168,7 +168,8 @@ struct ScopedAioContext {
struct UsbFfsConnection : public Connection {
UsbFfsConnection(unique_fd control, unique_fd read, unique_fd write,
std::promise<void> destruction_notifier)
- : stopped_(false),
+ : worker_started_(false),
+ stopped_(false),
destruction_notifier_(std::move(destruction_notifier)),
control_fd_(std::move(control)),
read_fd_(std::move(read)),
@@ -194,6 +195,7 @@ struct UsbFfsConnection : public Connection {
// We need to explicitly close our file descriptors before we notify our destruction,
// because the thread listening on the future will immediately try to reopen the endpoint.
+ aio_context_.reset();
control_fd_.reset();
read_fd_.reset();
write_fd_.reset();
@@ -274,11 +276,16 @@ struct UsbFfsConnection : public Connection {
{ .fd = control_fd_.get(), .events = POLLIN, .revents = 0 },
{ .fd = monitor_event_fd_.get(), .events = POLLIN, .revents = 0 },
};
- int rc = TEMP_FAILURE_RETRY(adb_poll(pfd, 2, -1));
+
+ // If we don't see our first bind within a second, try again.
+ int timeout_ms = bound ? -1 : 1000;
+
+ int rc = TEMP_FAILURE_RETRY(adb_poll(pfd, 2, timeout_ms));
if (rc == -1) {
PLOG(FATAL) << "poll on USB control fd failed";
} else if (rc == 0) {
- LOG(FATAL) << "poll on USB control fd returned 0";
+ LOG(WARNING) << "timed out while waiting for FUNCTIONFS_BIND, trying again";
+ break;
}
if (pfd[1].revents) {
@@ -330,13 +337,13 @@ struct UsbFfsConnection : public Connection {
}
StopWorker();
- aio_context_.reset();
- read_fd_.reset();
- write_fd_.reset();
+ HandleError("monitor thread finished");
});
}
void StartWorker() {
+ CHECK(!worker_started_);
+ worker_started_ = true;
worker_thread_ = std::thread([this]() {
adb_thread_setname("UsbFfs-worker");
for (size_t i = 0; i < kUsbReadQueueDepth; ++i) {
@@ -361,6 +368,10 @@ struct UsbFfsConnection : public Connection {
}
void StopWorker() {
+ if (!worker_started_) {
+ return;
+ }
+
pthread_t worker_thread_handle = worker_thread_.native_handle();
while (true) {
int rc = pthread_kill(worker_thread_handle, kInterruptionSignal);
@@ -590,6 +601,8 @@ struct UsbFfsConnection : public Connection {
}
std::thread monitor_thread_;
+
+ bool worker_started_;
std::thread worker_thread_;
std::atomic<bool> stopped_;