Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 5ba6802e authored by Jerry Zhang's avatar Jerry Zhang
Browse files

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 6e9a3275)
parent 3464bc4b
Loading
Loading
Loading
Loading
+20 −14
Original line number Diff line number Diff line
@@ -439,24 +439,30 @@ 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);
    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) {
        D("[ aio: got error waiting %s (%d) ]", read ? "read" : "write", errno);
        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;
            D("[ aio: got error event on %s (%d) ]", read ? "read" : "write", errno);
                errno = -aiob->events[i].res;
                PLOG(ERROR) << "aio: got error event on " << (read ? "read" : "write")
                            << " total bufs " << num_bufs;
                return -1;
            }
        }
        return 0;
    }
}

static int usb_ffs_aio_read(usb_handle* h, void* data, int len) {
    return usb_ffs_do_aio(h, data, len, true);