mirror of
https://github.com/RetroDECK/ES-DE.git
synced 2025-03-06 14:27:43 +00:00
Fixed a libcurl memory leak in the scraper.
This commit is contained in:
parent
da37e2c11a
commit
923d1df479
|
@ -43,7 +43,8 @@ GuiScraperSearch::GuiScraperSearch(
|
|||
mBusyAnim(window),
|
||||
mSearchType(type),
|
||||
mScrapeCount(scrapeCount),
|
||||
mScrapeRatings(false)
|
||||
mScrapeRatings(false),
|
||||
mFoundGame(false)
|
||||
{
|
||||
addChild(&mGrid);
|
||||
|
||||
|
@ -124,6 +125,11 @@ GuiScraperSearch::GuiScraperSearch(
|
|||
updateViewStyle();
|
||||
}
|
||||
|
||||
GuiScraperSearch::~GuiScraperSearch()
|
||||
{
|
||||
HttpReq::cleanupCurlMulti();
|
||||
}
|
||||
|
||||
void GuiScraperSearch::onSizeChanged()
|
||||
{
|
||||
mGrid.setSize(mSize);
|
||||
|
|
|
@ -38,6 +38,7 @@ public:
|
|||
};
|
||||
|
||||
GuiScraperSearch(Window* window, SearchType searchType, unsigned int scrapeCount = 1);
|
||||
~GuiScraperSearch();
|
||||
|
||||
void search(const ScraperSearchParams& params);
|
||||
void openInputScreen(ScraperSearchParams& from);
|
||||
|
|
|
@ -149,7 +149,7 @@ protected:
|
|||
friend std::unique_ptr<ScraperSearchHandle>
|
||||
startMediaURLsFetch(const std::string& gameIDs);
|
||||
|
||||
std::queue< std::unique_ptr<ScraperRequest> > mRequestQueue;
|
||||
std::queue<std::unique_ptr<ScraperRequest>> mRequestQueue;
|
||||
std::vector<ScraperSearchResult> mResults;
|
||||
};
|
||||
|
||||
|
|
|
@ -16,8 +16,7 @@
|
|||
|
||||
#include <assert.h>
|
||||
|
||||
CURLM* HttpReq::s_multi_handle = curl_multi_init();
|
||||
|
||||
CURLM* HttpReq::s_multi_handle;
|
||||
std::map<CURL*, HttpReq*> HttpReq::s_requests;
|
||||
|
||||
std::string HttpReq::urlEncode(const std::string &s)
|
||||
|
@ -26,7 +25,7 @@ std::string HttpReq::urlEncode(const std::string &s)
|
|||
"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_.~";
|
||||
|
||||
std::string escaped="";
|
||||
for (size_t i=0; i<s.length(); i++) {
|
||||
for (size_t i = 0; i < s.length(); i++) {
|
||||
if (unreserved.find_first_of(s[i]) != std::string::npos) {
|
||||
escaped.push_back(s[i]);
|
||||
}
|
||||
|
@ -50,6 +49,12 @@ bool HttpReq::isUrl(const std::string& str)
|
|||
|
||||
HttpReq::HttpReq(const std::string& url) : mStatus(REQ_IN_PROGRESS), mHandle(nullptr)
|
||||
{
|
||||
// The multi-handle is cleaned up via a call from GuiScraperSearch after the scraping
|
||||
// has been completed for a game, meaning the handle is valid for all cURL requests
|
||||
// performed for the current game.
|
||||
if (!s_multi_handle)
|
||||
s_multi_handle = curl_multi_init();
|
||||
|
||||
mHandle = curl_easy_init();
|
||||
|
||||
// On Windows, use the bundled cURL TLS/SSL certificates (which actually come from the
|
||||
|
@ -200,14 +205,8 @@ std::string HttpReq::getErrorMsg()
|
|||
// Return value is number of elements successfully read.
|
||||
size_t HttpReq::write_content(void* buff, size_t size, size_t nmemb, void* req_ptr)
|
||||
{
|
||||
std::stringstream& ss = ((HttpReq*)req_ptr)->mContent;
|
||||
ss.write((char*)buff, size * nmemb);
|
||||
std::stringstream& ss = (static_cast<HttpReq*>(req_ptr))->mContent;
|
||||
ss.write(static_cast<char*>(buff), size * nmemb);
|
||||
|
||||
return nmemb;
|
||||
}
|
||||
|
||||
// Used as a curl callback.
|
||||
//int HttpReq::update_progress(void* req_ptr, double dlTotal,
|
||||
// double dlNow, double ulTotal, double ulNow)
|
||||
//{
|
||||
//}
|
||||
|
|
|
@ -40,31 +40,34 @@ class HttpReq
|
|||
{
|
||||
public:
|
||||
HttpReq(const std::string& url);
|
||||
|
||||
~HttpReq();
|
||||
|
||||
enum Status {
|
||||
REQ_IN_PROGRESS, // Request is in progress.
|
||||
REQ_SUCCESS, // Request completed successfully, get it with getContent().
|
||||
|
||||
REQ_IO_ERROR, // Some error happened, get it with getErrorMsg().
|
||||
REQ_BAD_STATUS_CODE, // Some invalid HTTP response status code happened (non-200).
|
||||
REQ_INVALID_RESPONSE // The HTTP response was invalid.
|
||||
};
|
||||
|
||||
Status status(); // Process any received data and return the status afterwards.
|
||||
|
||||
std::string getErrorMsg();
|
||||
|
||||
std::string getContent() const; // mStatus must be REQ_SUCCESS.
|
||||
|
||||
static std::string urlEncode(const std::string &s);
|
||||
static bool isUrl(const std::string& s);
|
||||
|
||||
static void cleanupCurlMulti()
|
||||
{
|
||||
if (s_multi_handle != nullptr) {
|
||||
curl_multi_cleanup(s_multi_handle);
|
||||
s_multi_handle = nullptr;
|
||||
}
|
||||
};
|
||||
|
||||
private:
|
||||
static size_t write_content(void* buff, size_t size, size_t nmemb, void* req_ptr);
|
||||
//static int update_progress(void* req_ptr, double dlTotal, double dlNow,
|
||||
// double ulTotal, double ulNow);
|
||||
void onError(const char* msg);
|
||||
|
||||
// God dammit libcurl why can't you have some way to check the status of an
|
||||
// individual handle why do I have to handle ALL messages at once.
|
||||
|
@ -72,10 +75,7 @@ private:
|
|||
|
||||
static CURLM* s_multi_handle;
|
||||
|
||||
void onError(const char* msg);
|
||||
|
||||
CURL* mHandle;
|
||||
|
||||
Status mStatus;
|
||||
|
||||
std::stringstream mContent;
|
||||
|
|
Loading…
Reference in a new issue