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:
@@ -506,13 +506,12 @@ struct curlFileTransfer : public FileTransfer
|
||||
// loop with kj. until then curl will handle its timeouts internally.
|
||||
int64_t timeoutMs = INT64_MAX;
|
||||
|
||||
while (!quit) {
|
||||
checkInterrupt();
|
||||
|
||||
while (true) {
|
||||
{
|
||||
auto cancel = [&] { return std::move(state_.lock()->cancel); }();
|
||||
for (auto & [item, promise] : cancel) {
|
||||
curl_multi_remove_handle(curlm.get(), item->req.get());
|
||||
items.erase(item->req.get());
|
||||
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. */
|
||||
mc = curl_multi_poll(curlm.get(), nullptr, 0, std::min<int64_t>(timeoutMs, INT_MAX), nullptr);
|
||||
if (mc != CURLM_OK)
|
||||
|
||||
Reference in New Issue
Block a user