From 71cb7663930af8792c12558b8e9f02a7ce145d07 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Henrik=20Rydg=C3=A5rd?= Date: Sat, 17 Jun 2023 22:31:47 +0200 Subject: [PATCH] Fix re-entrancy issue in Downloader --- Common/Net/HTTPClient.cpp | 13 +++++++++---- Common/Net/HTTPClient.h | 3 +++ 2 files changed, 12 insertions(+), 4 deletions(-) diff --git a/Common/Net/HTTPClient.cpp b/Common/Net/HTTPClient.cpp index f1831ce297..43b30f7602 100644 --- a/Common/Net/HTTPClient.cpp +++ b/Common/Net/HTTPClient.cpp @@ -582,7 +582,7 @@ std::shared_ptr Downloader::StartDownload(const std::string &url, cons std::shared_ptr dl(new Download(RequestMethod::GET, url, "", "", outfile)); if (acceptMime) dl->SetAccept(acceptMime); - downloads_.push_back(dl); + newDownloads_.push_back(dl); dl->Start(); return dl; } @@ -596,7 +596,7 @@ std::shared_ptr Downloader::StartDownloadWithCallback( if (acceptMime) dl->SetAccept(acceptMime); dl->SetCallback(callback); - downloads_.push_back(dl); + newDownloads_.push_back(dl); dl->Start(); return dl; } @@ -608,15 +608,20 @@ std::shared_ptr Downloader::AsyncPostWithCallback( std::string postMime = "application/x-www-form-urlencoded"; std::shared_ptr dl(new Download(RequestMethod::POST, url, postData, postMime, Path())); dl->SetCallback(callback); - downloads_.push_back(dl); + newDownloads_.push_back(dl); dl->Start(); return dl; } void Downloader::Update() { + for (auto iter : newDownloads_) { + downloads_.push_back(iter); + } + newDownloads_.clear(); + restart: for (size_t i = 0; i < downloads_.size(); i++) { - auto &dl = downloads_[i]; + auto dl = downloads_[i]; if (dl->Done()) { dl->RunCallback(); dl->Join(); diff --git a/Common/Net/HTTPClient.h b/Common/Net/HTTPClient.h index 0aeab09472..f6b832b834 100644 --- a/Common/Net/HTTPClient.h +++ b/Common/Net/HTTPClient.h @@ -214,6 +214,9 @@ public: private: std::vector> downloads_; + // These get copied to downloads_ in Update(). It's so that callbacks can add new downloads + // while running. + std::vector> newDownloads_; }; } // http