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

Commit 7063c936 authored by Jerry Zhang's avatar Jerry Zhang
Browse files

Wait for threads to finish before returning.

Prevents the thread struct from being deallocated
before the thread has finished.

Bug: 35152606
Test: Transfer files in both directions, verify behavior when
interrupted

Change-Id: Ic247072234977709711366636e6a39031fbc125a
parent 97e6e199
Loading
Loading
Loading
Loading
+4 −0
Original line number Diff line number Diff line
@@ -96,6 +96,10 @@ std::thread pool[NUM_THREADS];

} // end anonymous namespace

aiocb::~aiocb() {
    CHECK(!thread.joinable());
}

void aio_pool_init(void(f)(int)) {
    CHECK(done == 1);
    done = 0;
+6 −0
Original line number Diff line number Diff line
@@ -48,6 +48,8 @@ struct aiocb {
    std::thread thread;
    ssize_t ret;
    int error;

    ~aiocb();
};

// Submit a request for IO to be completed
@@ -58,9 +60,13 @@ int aio_splice_write(struct aiocb *);

// Suspend current thread until given IO is complete, at which point
// its return value and any errors can be accessed
// All submitted requests must have a corresponding suspend.
// aiocb->aio_buf must refer to valid memory until after the suspend call
int aio_suspend(struct aiocb *[], int, const struct timespec *);
int aio_error(const struct aiocb *);
ssize_t aio_return(struct aiocb *);

// (Currently unimplemented)
int aio_cancel(int, struct aiocb *);

// Initialize a threadpool to perform IO. Only one pool can be
+16 −7
Original line number Diff line number Diff line
@@ -541,14 +541,12 @@ int MtpFfsHandle::receiveFile(mtp_file_range mfr) {
        if (file_length > 0) {
            length = std::min(static_cast<uint32_t>(MAX_FILE_CHUNK_SIZE), file_length);

            // Read data from USB
            if ((ret = readHandle(mBulkOut, data, length)) == -1) {
                return -1;
            }
            // Read data from USB, handle errors after waiting for write thread.
            ret = readHandle(mBulkOut, data, length);

            if (file_length != MAX_MTP_FILE_SIZE && ret < static_cast<int>(length)) {
                ret = -1;
                errno = EIO;
                return -1;
            }
            read = true;
        }
@@ -569,6 +567,11 @@ int MtpFfsHandle::receiveFile(mtp_file_range mfr) {
            write = false;
        }

        // If there was an error reading above
        if (ret == -1) {
            return -1;
        }

        if (read) {
            // Enqueue a new write request
            aio.aio_buf = data;
@@ -626,6 +629,7 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) {
    aio.aio_fildes = mfr.fd;
    struct aiocb *aiol[] = {&aio};
    int ret, length;
    int error = 0;
    bool read = false;
    bool write = false;

@@ -669,6 +673,10 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) {
            write = true;
        }

        if (error == -1) {
            return -1;
        }

        if (file_length > 0) {
            length = std::min(static_cast<uint64_t>(MAX_FILE_CHUNK_SIZE), file_length);
            // Queue up another read
@@ -680,8 +688,9 @@ int MtpFfsHandle::sendFile(mtp_file_range mfr) {
        }

        if (write) {
            if (writeHandle(mBulkIn, data2, ret) == -1)
                return -1;
            if (writeHandle(mBulkIn, data2, ret) == -1) {
                error = -1;
            }
            write = false;
        }
    }