Compare commits

...

1 Commits

Author SHA1 Message Date
Félix Baylac-Jacqué 8b73ff45cc Make curl threadsafe again. 2019-07-31 22:54:03 +02:00
1 changed files with 19 additions and 5 deletions

View File

@ -505,6 +505,17 @@ struct CurlDownloader : public Downloader
stopWorkerThread(); stopWorkerThread();
}); });
/* NINJATRAPPEUR_TOREMOVE: quick test */
auto curlmn = curl_multi_init();
#if LIBCURL_VERSION_NUM >= 0x072b00 // Multiplex requires >= 7.43.0
curl_multi_setopt(curlm, CURLMOPT_PIPELINING, CURLPIPE_MULTIPLEX);
#endif
#if LIBCURL_VERSION_NUM >= 0x071e00 // Max connections requires >= 7.30.0
curl_multi_setopt(curlm, CURLMOPT_MAX_TOTAL_CONNECTIONS,
downloadSettings.httpConnections.get());
#endif
/* =================== */
std::map<CURL *, std::shared_ptr<DownloadItem>> items; std::map<CURL *, std::shared_ptr<DownloadItem>> items;
bool quit = false; bool quit = false;
@ -516,19 +527,19 @@ struct CurlDownloader : public Downloader
/* Let curl do its thing. */ /* Let curl do its thing. */
int running; int running;
CURLMcode mc = curl_multi_perform(curlm, &running); CURLMcode mc = curl_multi_perform(curlmn, &running);
if (mc != CURLM_OK) if (mc != CURLM_OK)
throw nix::Error(format("unexpected error from curl_multi_perform(): %s") % curl_multi_strerror(mc)); throw nix::Error(format("unexpected error from curl_multi_perform(): %s") % curl_multi_strerror(mc));
/* Set the promises of any finished requests. */ /* Set the promises of any finished requests. */
CURLMsg * msg; CURLMsg * msg;
int left; int left;
while ((msg = curl_multi_info_read(curlm, &left))) { while ((msg = curl_multi_info_read(curlmn, &left))) {
if (msg->msg == CURLMSG_DONE) { if (msg->msg == CURLMSG_DONE) {
auto i = items.find(msg->easy_handle); auto i = items.find(msg->easy_handle);
assert(i != items.end()); assert(i != items.end());
i->second->finish(msg->data.result); i->second->finish(msg->data.result);
curl_multi_remove_handle(curlm, i->second->req); curl_multi_remove_handle(curlmn, i->second->req);
i->second->active = false; i->second->active = false;
items.erase(i); items.erase(i);
} }
@ -546,7 +557,7 @@ struct CurlDownloader : public Downloader
? std::max(0, (int) std::chrono::duration_cast<std::chrono::milliseconds>(nextWakeup - std::chrono::steady_clock::now()).count()) ? std::max(0, (int) std::chrono::duration_cast<std::chrono::milliseconds>(nextWakeup - std::chrono::steady_clock::now()).count())
: maxSleepTimeMs; : maxSleepTimeMs;
vomit("download thread waiting for %d ms", sleepTimeMs); vomit("download thread waiting for %d ms", sleepTimeMs);
mc = curl_multi_wait(curlm, extraFDs, 1, sleepTimeMs, &numfds); mc = curl_multi_wait(curlmn, extraFDs, 1, sleepTimeMs, &numfds);
if (mc != CURLM_OK) if (mc != CURLM_OK)
throw nix::Error(format("unexpected error from curl_multi_wait(): %s") % curl_multi_strerror(mc)); throw nix::Error(format("unexpected error from curl_multi_wait(): %s") % curl_multi_strerror(mc));
@ -585,11 +596,14 @@ struct CurlDownloader : public Downloader
for (auto & item : incoming) { for (auto & item : incoming) {
debug("starting %s of %s", item->request.verb(), item->request.uri); debug("starting %s of %s", item->request.verb(), item->request.uri);
item->init(); item->init();
curl_multi_add_handle(curlm, item->req); curl_multi_add_handle(curlmn, item->req);
item->active = true; item->active = true;
items[item->req] = item; items[item->req] = item;
} }
} }
/* NINJATRPPEUR_TODO test stuff, toremove */
if (curlmn) curl_multi_cleanup(curlmn);
/* END */
debug("download thread shutting down"); debug("download thread shutting down");
} }