diff options
author | Kelvin Zhang <zhangkelvin@google.com> | 2020-12-15 20:12:18 +0100 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2020-12-15 20:12:18 +0100 |
commit | 51ee1b064a2772b72c685dd5d2b6d37fc78a687d (patch) | |
tree | 19a23c8af0e6983b885fd997bef189f2088f8cd6 | |
parent | [automerger skipped] Import translations. DO NOT MERGE ANYWHERE am: b1b27d1113 -s ours (diff) | |
parent | Merge "Do not call exit() immediately after serving sideload" am: a8e394942e (diff) | |
download | android_bootable_recovery-51ee1b064a2772b72c685dd5d2b6d37fc78a687d.tar android_bootable_recovery-51ee1b064a2772b72c685dd5d2b6d37fc78a687d.tar.gz android_bootable_recovery-51ee1b064a2772b72c685dd5d2b6d37fc78a687d.tar.bz2 android_bootable_recovery-51ee1b064a2772b72c685dd5d2b6d37fc78a687d.tar.lz android_bootable_recovery-51ee1b064a2772b72c685dd5d2b6d37fc78a687d.tar.xz android_bootable_recovery-51ee1b064a2772b72c685dd5d2b6d37fc78a687d.tar.zst android_bootable_recovery-51ee1b064a2772b72c685dd5d2b6d37fc78a687d.zip |
-rw-r--r-- | minadbd/minadbd_services.cpp | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/minadbd/minadbd_services.cpp b/minadbd/minadbd_services.cpp index ff91ba931..0abe8675b 100644 --- a/minadbd/minadbd_services.cpp +++ b/minadbd/minadbd_services.cpp @@ -23,6 +23,7 @@ #include <string.h> #include <unistd.h> +#include <chrono> #include <functional> #include <memory> #include <set> @@ -142,10 +143,48 @@ static MinadbdErrorCode RunAdbFuseSideload(int sfd, const std::string& args, return kMinadbdSuccess; } +static bool WaitForSocketClose(int fd, std::chrono::milliseconds timeout) { + const auto begin = std::chrono::steady_clock::now(); + const auto end = begin + timeout; + while (std::chrono::steady_clock::now() < end) { + // We don't care about reading the socket, we just want to wait until + // socket closes. In this case .events = 0 will tell the kernel to wait + // for close events. + struct pollfd pfd = { .fd = fd, .events = 0 }; + auto timeout_ms = std::chrono::duration_cast<std::chrono::milliseconds>( + end - std::chrono::steady_clock::now()) + .count(); + int rc = TEMP_FAILURE_RETRY(adb_poll(&pfd, 1, timeout_ms)); + if (rc == 1) { + LOG(INFO) << "revents: " << pfd.revents; + if (pfd.revents & (POLLHUP | POLLRDHUP)) { + return true; + } + } else { + PLOG(ERROR) << "poll() failed"; + // poll failed, almost definitely due to timeout + // If not, you're screwed anyway, because it probably means the kernel ran + // out of memory. + return false; + } + } + return false; +} + // Sideload service always exits after serving an install command. static void SideloadHostService(unique_fd sfd, const std::string& args) { + using namespace std::chrono_literals; MinadbdCommandStatus status; - exit(RunAdbFuseSideload(sfd.get(), args, &status)); + auto error = RunAdbFuseSideload(sfd.get(), args, &status); + // No need to wait if the socket is already closed, meaning the other end + // already exited for some reason. + if (error != kMinadbdHostSocketIOError) { + // We sleep for a little bit just to wait for the host to receive last + // "DONEDONE" message. However minadbd process is likely to get terminated + // early due to exit_on_close + WaitForSocketClose(sfd, 3000ms); + } + exit(error); } // Rescue service waits for the next command after an install command. |