libstore: delocalize TransferSource
future changes will need to add template functions to this class, which
cannot be done for classes declared locally in unctions. otherwise this
is mostly code motion to clean up enqueueFileTransfer a little further.
Change-Id: If9a9d9eb47ceadfa75a4eebd54e2db39f2305643
This commit is contained in:
parent
1338e93bc9
commit
d75c399b29
|
@ -847,6 +847,14 @@ struct curlFileTransfer : public FileTransfer
|
|||
return std::move(*eager);
|
||||
}
|
||||
|
||||
auto source = make_box_ptr<TransferSource>(*this, uri, headers, std::move(data), noBody);
|
||||
auto metadata = source->startTransfer();
|
||||
source->awaitData();
|
||||
return {std::move(metadata), std::move(source)};
|
||||
}
|
||||
|
||||
struct TransferSource : Source
|
||||
{
|
||||
struct State {
|
||||
bool done = false;
|
||||
std::exception_ptr exc;
|
||||
|
@ -854,20 +862,58 @@ struct curlFileTransfer : public FileTransfer
|
|||
std::condition_variable avail;
|
||||
};
|
||||
|
||||
auto _state = std::make_shared<Sync<State>>();
|
||||
curlFileTransfer & parent;
|
||||
std::string uri;
|
||||
Headers headers;
|
||||
std::optional<std::string> data;
|
||||
bool noBody;
|
||||
|
||||
auto item = std::make_shared<TransferItem>(
|
||||
*this,
|
||||
const std::shared_ptr<Sync<State>> _state = std::make_shared<Sync<State>>();
|
||||
std::shared_ptr<TransferItem> transfer;
|
||||
std::string chunk;
|
||||
std::string_view buffered;
|
||||
|
||||
TransferSource(
|
||||
curlFileTransfer & parent,
|
||||
const std::string & uri,
|
||||
const Headers & headers,
|
||||
std::optional<std::string> data,
|
||||
bool noBody
|
||||
)
|
||||
: parent(parent)
|
||||
, uri(uri)
|
||||
, headers(headers)
|
||||
, data(std::move(data))
|
||||
, noBody(noBody)
|
||||
{
|
||||
}
|
||||
|
||||
~TransferSource()
|
||||
{
|
||||
// wake up the download thread if it's still going and have it abort
|
||||
try {
|
||||
if (transfer) {
|
||||
transfer->cancel();
|
||||
}
|
||||
} catch (...) {
|
||||
ignoreExceptionInDestructor();
|
||||
}
|
||||
}
|
||||
|
||||
FileTransferResult startTransfer()
|
||||
{
|
||||
transfer = std::make_shared<TransferItem>(
|
||||
parent,
|
||||
uri,
|
||||
headers,
|
||||
getCurActivity(),
|
||||
[_state](std::exception_ptr ex) {
|
||||
[_state{_state}](std::exception_ptr ex) {
|
||||
auto state(_state->lock());
|
||||
state->done = true;
|
||||
state->exc = ex;
|
||||
state->avail.notify_one();
|
||||
},
|
||||
[_state](std::string_view data) {
|
||||
[_state{_state}](std::string_view data) {
|
||||
auto state(_state->lock());
|
||||
|
||||
/* If the buffer is full, then go to sleep until the calling
|
||||
|
@ -888,31 +934,8 @@ struct curlFileTransfer : public FileTransfer
|
|||
std::move(data),
|
||||
noBody
|
||||
);
|
||||
enqueueItem(item);
|
||||
|
||||
struct TransferSource : Source
|
||||
{
|
||||
const std::shared_ptr<Sync<State>> _state;
|
||||
std::shared_ptr<TransferItem> transfer;
|
||||
std::string chunk;
|
||||
std::string_view buffered;
|
||||
|
||||
explicit TransferSource(
|
||||
const std::shared_ptr<Sync<State>> & state, std::shared_ptr<TransferItem> transfer
|
||||
)
|
||||
: _state(state)
|
||||
, transfer(std::move(transfer))
|
||||
{
|
||||
}
|
||||
|
||||
~TransferSource()
|
||||
{
|
||||
// wake up the download thread if it's still going and have it abort
|
||||
try {
|
||||
transfer->cancel();
|
||||
} catch (...) {
|
||||
ignoreExceptionInDestructor();
|
||||
}
|
||||
parent.enqueueItem(transfer);
|
||||
return transfer->metadataPromise.get_future().get();
|
||||
}
|
||||
|
||||
void awaitData()
|
||||
|
@ -969,12 +992,6 @@ struct curlFileTransfer : public FileTransfer
|
|||
}
|
||||
};
|
||||
|
||||
auto metadata = item->metadataPromise.get_future().get();
|
||||
auto source = make_box_ptr<TransferSource>(_state, item);
|
||||
source->awaitData();
|
||||
return {std::move(metadata), std::move(source)};
|
||||
}
|
||||
|
||||
bool exists(const std::string & uri, const Headers & headers) override
|
||||
{
|
||||
try {
|
||||
|
|
Loading…
Reference in a new issue