From 121edecf654ec084274ba1a779c7140082f4115d Mon Sep 17 00:00:00 2001 From: eldritch horrors Date: Sun, 5 May 2024 17:08:59 +0200 Subject: filetransfer: extract decompressor creation this will be necessary if we want download() to return a source instead of consuming a sink, which will in turn be needed to remove coroutines. Change-Id: I34ec241e9bbc5d32fbcd243b244e29c3757533aa --- src/libstore/filetransfer.cc | 23 +++++++++++------------ 1 file changed, 11 insertions(+), 12 deletions(-) (limited to 'src/libstore') diff --git a/src/libstore/filetransfer.cc b/src/libstore/filetransfer.cc index aa8f4be1d..a0e3fd586 100644 --- a/src/libstore/filetransfer.cc +++ b/src/libstore/filetransfer.cc @@ -710,9 +710,8 @@ struct curlFileTransfer : public FileTransfer struct State { bool done = false, failed = false; std::exception_ptr exc; - std::string data; + std::string data, encoding; std::condition_variable avail, request; - std::unique_ptr decompressor; }; auto _state = std::make_shared>(); @@ -736,7 +735,7 @@ struct curlFileTransfer : public FileTransfer state->avail.notify_one(); state->request.notify_one(); }}, - [_state, &sink](TransferItem & transfer, std::string_view data) { + [_state](TransferItem & transfer, std::string_view data) { auto state(_state->lock()); if (state->failed) { @@ -744,10 +743,6 @@ struct curlFileTransfer : public FileTransfer throw std::exception{}; } - if (!state->decompressor) { - state->decompressor = makeDecompressionSink(transfer.encoding, sink); - } - /* If the buffer is full, then go to sleep until the calling thread wakes us up (i.e. when it has removed data from the buffer). We don't wait forever to prevent stalling the @@ -764,11 +759,12 @@ struct curlFileTransfer : public FileTransfer state->avail.notify_one(); }); + std::unique_ptr decompressor; + while (true) { checkInterrupt(); std::string chunk; - FinishSink * sink = nullptr; /* Grab data if available, otherwise wait for the download thread to wake us up. */ @@ -779,8 +775,8 @@ struct curlFileTransfer : public FileTransfer if (state->done) { if (state->exc) std::rethrow_exception(state->exc); - if (state->decompressor) { - state->decompressor->finish(); + if (decompressor) { + decompressor->finish(); } return; } @@ -791,10 +787,13 @@ struct curlFileTransfer : public FileTransfer } chunk = std::move(state->data); - sink = state->decompressor.get(); /* Reset state->data after the move, since we check data.empty() */ state->data = ""; + if (!decompressor) { + decompressor = makeDecompressionSink(state->encoding, sink); + } + state->request.notify_one(); } @@ -802,7 +801,7 @@ struct curlFileTransfer : public FileTransfer if it's blocked on a full buffer. We don't hold the state lock while doing this to prevent blocking the download thread if sink() takes a long time. */ - (*sink)(chunk); + (*decompressor)(chunk); } } }; -- cgit v1.2.3