forked from lix-project/lix
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
This commit is contained in:
parent
b22f2bc8e9
commit
3b1298efce
1 changed files with 19 additions and 30 deletions
|
@ -861,52 +861,41 @@ struct curlFileTransfer : public FileTransfer
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
void awaitData()
|
bool awaitData()
|
||||||
{
|
{
|
||||||
withRetries([&] {
|
return withRetries([&] {
|
||||||
/* Grab data if available, otherwise wait for the download
|
/* Grab data if available, otherwise wait for the download
|
||||||
thread to wake us up. */
|
thread to wake us up. */
|
||||||
while (buffered.empty()) {
|
while (buffered.empty()) {
|
||||||
auto state(transfer->downloadState.lock());
|
auto state(transfer->downloadState.lock());
|
||||||
|
|
||||||
if (state->data.empty()) {
|
if (!state->data.empty()) {
|
||||||
if (state->exc) {
|
chunk = std::move(state->data);
|
||||||
std::rethrow_exception(state->exc);
|
buffered = chunk;
|
||||||
} else if (state->done) {
|
totalReceived += chunk.size();
|
||||||
return;
|
parent.unpause(transfer);
|
||||||
}
|
} else if (state->exc) {
|
||||||
|
std::rethrow_exception(state->exc);
|
||||||
|
} else if (state->done) {
|
||||||
|
return false;
|
||||||
|
} else {
|
||||||
parent.unpause(transfer);
|
parent.unpause(transfer);
|
||||||
state.wait(transfer->downloadEvent);
|
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
|
size_t read(char * data, size_t len) override
|
||||||
{
|
{
|
||||||
auto readPartial = [this](char * data, size_t len) -> size_t {
|
size_t total = 0;
|
||||||
const auto available = std::min(len, buffered.size());
|
while (total < len && awaitData()) {
|
||||||
if (available == 0u) return 0u;
|
const auto available = std::min(len - total, buffered.size());
|
||||||
|
memcpy(data + total, buffered.data(), available);
|
||||||
memcpy(data, buffered.data(), available);
|
|
||||||
buffered.remove_prefix(available);
|
buffered.remove_prefix(available);
|
||||||
return available;
|
total += 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;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (total == 0) {
|
if (total == 0) {
|
||||||
|
|
Loading…
Reference in a new issue