From 5ba6802e9ab30855212d9aae753363f68a4e30e2 Mon Sep 17 00:00:00 2001 From: Jerry Zhang Date: Mon, 19 Mar 2018 17:54:39 -0700 Subject: [PATCH] adb: Retry io in case of interrupt io_submit sleeps waiting for the gadget to be enabled. Currently if that sleep is interrupted it will shut down adb, causing it to have to start back up again. Rather than return EINTR if interrupted, io_submit actually completes and the EINTR is found later when looking through events. Since an io that is interrupted will be small anyway, add a loop to retry small ios. Also upgrade aio logs in accordance with their importance. Fixes: 75981904 Test: adb works, logs show successful interrupt handling Change-Id: I35973fce130ee849ce59fef80d15b65afb816ba4 (cherry picked from commit 6e9a327504e6aa2488b736fd5592525278a0916f) --- adb/daemon/usb.cpp | 34 ++++++++++++++++++++-------------- 1 file changed, 20 insertions(+), 14 deletions(-) diff --git a/adb/daemon/usb.cpp b/adb/daemon/usb.cpp index ab11bdd1b..263303fde 100644 --- a/adb/daemon/usb.cpp +++ b/adb/daemon/usb.cpp @@ -439,23 +439,29 @@ static int usb_ffs_do_aio(usb_handle* h, const void* data, int len, bool read) { num_bufs += 1; } - if (io_submit(aiob->ctx, num_bufs, aiob->iocbs.data()) < num_bufs) { - D("[ aio: got error submitting %s (%d) ]", read ? "read" : "write", errno); - return -1; - } - if (TEMP_FAILURE_RETRY( - io_getevents(aiob->ctx, num_bufs, num_bufs, aiob->events.data(), nullptr)) < num_bufs) { - D("[ aio: got error waiting %s (%d) ]", read ? "read" : "write", errno); - return -1; - } - for (int i = 0; i < num_bufs; i++) { - if (aiob->events[i].res < 0) { - errno = aiob->events[i].res; - D("[ aio: got error event on %s (%d) ]", read ? "read" : "write", errno); + while (true) { + if (TEMP_FAILURE_RETRY(io_submit(aiob->ctx, num_bufs, aiob->iocbs.data())) < num_bufs) { + PLOG(ERROR) << "aio: got error submitting " << (read ? "read" : "write"); return -1; } + if (TEMP_FAILURE_RETRY(io_getevents(aiob->ctx, num_bufs, num_bufs, aiob->events.data(), + nullptr)) < num_bufs) { + PLOG(ERROR) << "aio: got error waiting " << (read ? "read" : "write"); + return -1; + } + if (num_bufs == 1 && aiob->events[0].res == -EINTR) { + continue; + } + for (int i = 0; i < num_bufs; i++) { + if (aiob->events[i].res < 0) { + errno = -aiob->events[i].res; + PLOG(ERROR) << "aio: got error event on " << (read ? "read" : "write") + << " total bufs " << num_bufs; + return -1; + } + } + return 0; } - return 0; } static int usb_ffs_aio_read(usb_handle* h, void* data, int len) {