From 3b1298efcedc638c672057155ac99ecc5661f2ab Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Fri, 15 Nov 2024 16:15:11 +0100 Subject: [PATCH] libstore: simplify TransferSource::read things can be much simpler if the read loop knows whether the transfer is done or not. this information is available, let's pass it back down Change-Id: Idb99afeb06a0d7a0999c3f4a1c6ce5adeab5f054 --- src/libstore/filetransfer.cc | 49 ++++++++++++++---------------------- 1 file changed, 19 insertions(+), 30 deletions(-) diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index f43a4341a..75e3667fc 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -861,52 +861,41 @@ struct curlFileTransfer : public FileTransfer return true; } - void awaitData() + bool awaitData() { - withRetries([&] { + return withRetries([&] { /* Grab data if available, otherwise wait for the download thread to wake us up. */ while (buffered.empty()) { auto state(transfer->downloadState.lock()); - if (state->data.empty()) { - if (state->exc) { - std::rethrow_exception(state->exc); - } else if (state->done) { - return; - } - + if (!state->data.empty()) { + chunk = std::move(state->data); + buffered = chunk; + totalReceived += chunk.size(); + parent.unpause(transfer); + } else if (state->exc) { + std::rethrow_exception(state->exc); + } else if (state->done) { + return false; + } else { parent.unpause(transfer); state.wait(transfer->downloadEvent); } - - chunk = std::move(state->data); - buffered = chunk; - totalReceived += chunk.size(); - parent.unpause(transfer); } + + return true; }); } size_t read(char * data, size_t len) override { - auto readPartial = [this](char * data, size_t len) -> size_t { - const auto available = std::min(len, buffered.size()); - if (available == 0u) return 0u; - - memcpy(data, buffered.data(), available); + size_t total = 0; + while (total < len && awaitData()) { + const auto available = std::min(len - total, buffered.size()); + memcpy(data + total, buffered.data(), available); buffered.remove_prefix(available); - return available; - }; - size_t total = readPartial(data, len); - - while (total < len) { - awaitData(); - const auto current = readPartial(data + total, len - total); - total += current; - if (total == 0 || current == 0) { - break; - } + total += available; } if (total == 0) {