summaryrefslogtreecommitdiffstats
path: root/adb/daemon/usb.cpp
diff options
context:
space:
mode:
authorJosh Gao <jmgao@google.com>2019-03-01 10:16:46 +0000
committerGerrit Code Review <noreply-gerritcodereview@google.com>2019-03-01 10:16:46 +0000
commitb530537d463eb1497b144b35722788c0b90dc62b (patch)
tree23cd88644e936bff9255a7a6398c94c0e6f50b75 /adb/daemon/usb.cpp
parent7669ea5a44563d7ceebb2adcb03838b57051a601 (diff)
parente778b3ad71b20bc73043bbb49877475fb18c0b09 (diff)
downloadsystem_core-b530537d463eb1497b144b35722788c0b90dc62b.tar.gz
system_core-b530537d463eb1497b144b35722788c0b90dc62b.tar.bz2
system_core-b530537d463eb1497b144b35722788c0b90dc62b.zip
Merge "adbd: fix a case where we can fail to join a thread."
Diffstat (limited to 'adb/daemon/usb.cpp')
-rw-r--r--adb/daemon/usb.cpp53
1 files changed, 29 insertions, 24 deletions
diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp
index ff618b050..598f2cd37 100644
--- a/adb/daemon/usb.cpp
+++ b/adb/daemon/usb.cpp
@@ -260,7 +260,6 @@ struct UsbFfsConnection : public Connection {
// until it dies, and then report failure to the transport via HandleError, which will
// eventually result in the transport being destroyed, which will result in UsbFfsConnection
// being destroyed, which unblocks the open thread and restarts this entire process.
- static constexpr int kInterruptionSignal = SIGUSR1;
static std::once_flag handler_once;
std::call_once(handler_once, []() { signal(kInterruptionSignal, [](int) {}); });
@@ -286,6 +285,7 @@ struct UsbFfsConnection : public Connection {
} else if (rc == 0) {
// Something in the kernel presumably went wrong.
// Close our endpoints, wait for a bit, and then try again.
+ StopWorker();
aio_context_.reset();
read_fd_.reset();
write_fd_.reset();
@@ -311,7 +311,7 @@ struct UsbFfsConnection : public Connection {
switch (event.type) {
case FUNCTIONFS_BIND:
- CHECK(!started) << "received FUNCTIONFS_ENABLE while already bound?";
+ CHECK(!bound) << "received FUNCTIONFS_BIND while already bound?";
bound = true;
break;
@@ -327,28 +327,7 @@ struct UsbFfsConnection : public Connection {
}
}
- pthread_t worker_thread_handle = worker_thread_.native_handle();
- while (true) {
- int rc = pthread_kill(worker_thread_handle, kInterruptionSignal);
- if (rc != 0) {
- LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc);
- break;
- }
-
- std::this_thread::sleep_for(100ms);
-
- rc = pthread_kill(worker_thread_handle, 0);
- if (rc == 0) {
- continue;
- } else if (rc == ESRCH) {
- break;
- } else {
- LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc);
- }
- }
-
- worker_thread_.join();
-
+ StopWorker();
aio_context_.reset();
read_fd_.reset();
write_fd_.reset();
@@ -379,6 +358,30 @@ struct UsbFfsConnection : public Connection {
});
}
+ void StopWorker() {
+ pthread_t worker_thread_handle = worker_thread_.native_handle();
+ while (true) {
+ int rc = pthread_kill(worker_thread_handle, kInterruptionSignal);
+ if (rc != 0) {
+ LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc);
+ break;
+ }
+
+ std::this_thread::sleep_for(100ms);
+
+ rc = pthread_kill(worker_thread_handle, 0);
+ if (rc == 0) {
+ continue;
+ } else if (rc == ESRCH) {
+ break;
+ } else {
+ LOG(ERROR) << "failed to send interruption signal to worker: " << strerror(rc);
+ }
+ }
+
+ worker_thread_.join();
+ }
+
void PrepareReadBlock(IoBlock* block, uint64_t id) {
block->pending = false;
block->payload = std::make_shared<Block>(kUsbReadSize);
@@ -615,6 +618,8 @@ struct UsbFfsConnection : public Connection {
std::deque<std::unique_ptr<IoBlock>> write_requests_ GUARDED_BY(write_mutex_);
size_t next_write_id_ GUARDED_BY(write_mutex_) = 0;
size_t writes_submitted_ GUARDED_BY(write_mutex_) = 0;
+
+ static constexpr int kInterruptionSignal = SIGUSR1;
};
void usb_init_legacy();