libstore: abort all curl transfers on interrupt
give the transfer progress callback a chance to register all transfers
as aborted when an interrupt event occurs. checkInterrupt() will throw
an Interrupted exception if an interrupt signal was caught, which will
immediately break out of the curl loop. it isn't even necessary within
the curl main loop as curl guarantees to call progress callbacks about
once per second (or more often), and we already abort transfers from a
progress update if a signal was caught. this may delay shutdown a bit,
but "about one second" as should not be noticeable in most situations.
fixes #577
Change-Id: Ida4e72732562bdf6560e4f182ecdcdb663c6dda5
This commit is contained in:
parent
c859d03013
commit
16bed313c6
|
@ -506,13 +506,12 @@ struct curlFileTransfer : public FileTransfer
|
||||||
// loop with kj. until then curl will handle its timeouts internally.
|
// loop with kj. until then curl will handle its timeouts internally.
|
||||||
int64_t timeoutMs = INT64_MAX;
|
int64_t timeoutMs = INT64_MAX;
|
||||||
|
|
||||||
while (!quit) {
|
while (true) {
|
||||||
checkInterrupt();
|
|
||||||
|
|
||||||
{
|
{
|
||||||
auto cancel = [&] { return std::move(state_.lock()->cancel); }();
|
auto cancel = [&] { return std::move(state_.lock()->cancel); }();
|
||||||
for (auto & [item, promise] : cancel) {
|
for (auto & [item, promise] : cancel) {
|
||||||
curl_multi_remove_handle(curlm.get(), item->req.get());
|
curl_multi_remove_handle(curlm.get(), item->req.get());
|
||||||
|
items.erase(item->req.get());
|
||||||
promise.set_value();
|
promise.set_value();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -536,6 +535,12 @@ struct curlFileTransfer : public FileTransfer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// only exit when all transfers are done (which will happen through the
|
||||||
|
// progress callback issuing an abort in the case of user interruption)
|
||||||
|
if (items.empty() && quit) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
/* Wait for activity, including wakeup events. */
|
/* Wait for activity, including wakeup events. */
|
||||||
mc = curl_multi_poll(curlm.get(), nullptr, 0, std::min<int64_t>(timeoutMs, INT_MAX), nullptr);
|
mc = curl_multi_poll(curlm.get(), nullptr, 0, std::min<int64_t>(timeoutMs, INT_MAX), nullptr);
|
||||||
if (mc != CURLM_OK)
|
if (mc != CURLM_OK)
|
||||||
|
|
Loading…
Reference in a new issue