Skip to content

Commit 9e52322

Browse files
committed
Fix startup bug
1 parent 1ef6850 commit 9e52322

6 files changed

Lines changed: 51 additions & 14 deletions

File tree

src/app/App.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,8 @@ App::App() = default;
3333
App::~App() {
3434
elog("~App: DownloadQueue stop");
3535
DownloadQueue::get().stop();
36+
elog("~App: clearing screens");
37+
m_screens.clear();
3638
elog("~App: ImageCache clear");
3739
if (m_renderer) ImageCache::get().clear(m_renderer);
3840
elog("~App: DestroyRenderer");
@@ -45,8 +47,6 @@ App::~App() {
4547
TTF_Quit();
4648
elog("~App: SDL_Quit");
4749
SDL_Quit();
48-
elog("~App: clearing screens");
49-
m_screens.clear();
5050
elog("~App: done");
5151
}
5252

src/net/HttpClient.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,23 @@
11
#include "HttpClient.h"
2+
#include <atomic>
23
#include "util/Logger.h"
34
#include <curl/curl.h>
45

6+
struct CancelCtx { std::atomic<bool>* flag; };
7+
8+
static int progressCallback(void* userdata, curl_off_t, curl_off_t, curl_off_t, curl_off_t) {
9+
auto* ctx = static_cast<CancelCtx*>(userdata);
10+
if (ctx && ctx->flag && ctx->flag->load()) return 1; // abort
11+
return 0;
12+
}
13+
514
static size_t writeCallback(void* ptr, size_t size, size_t nmemb, std::string* data) {
615
data->append((char*)ptr, size * nmemb);
716
return size * nmemb;
817
}
918

10-
bool HttpClient::get(const std::string& url, std::string& result) {
19+
bool HttpClient::get(const std::string& url, std::string& result,
20+
std::atomic<bool>* cancelFlag) {
1121
LOG_INFO("HTTP GET: %s", url.c_str());
1222

1323
CURL* curl = curl_easy_init();
@@ -27,6 +37,10 @@ bool HttpClient::get(const std::string& url, std::string& result) {
2737
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
2838
curl_easy_setopt(curl, CURLOPT_USERAGENT, "WiiUModStore/0.1");
2939

40+
CancelCtx ctx{ cancelFlag };
41+
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, progressCallback);
42+
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &ctx);
43+
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
3044
LOG_INFO("curl_easy_perform starting...");
3145
CURLcode res = curl_easy_perform(curl);
3246
LOG_INFO("curl_easy_perform returned: %d", res);

src/net/HttpClient.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,14 @@
11
#pragma once
22
#include <string>
3-
3+
#include <atomic>
4+
#include <curl/curl.h>
45
class HttpClient {
56
public:
67
// Fetches URL content into result string.
78
// Returns true on success, false on error.
8-
static bool get(const std::string& url, std::string& result);
9+
// If cancelFlag is set to true during the request, curl aborts immediately.
10+
static bool get(const std::string& url, std::string& result,
11+
std::atomic<bool>* cancelFlag = nullptr);
12+
private:
13+
static int progressCallback(void* userdata, curl_off_t, curl_off_t, curl_off_t, curl_off_t);
914
};

src/net/RepoManager.cpp

Lines changed: 16 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,5 @@
11
#include "RepoManager.h"
2+
#include <atomic>
23
#include "util/Logger.h"
34

45
#include <curl/curl.h>
@@ -21,7 +22,12 @@ bool RepoManager::validateUrl(const std::string& url) {
2122
return true;
2223
}
2324

24-
static std::string fetchUrl(const std::string& url, std::string& error) {
25+
struct FetchCancelCtx { std::atomic<bool>* flag; };
26+
static int fetchProgress(void* ud, curl_off_t, curl_off_t, curl_off_t, curl_off_t) {
27+
auto* ctx = static_cast<FetchCancelCtx*>(ud);
28+
return (ctx && ctx->flag && ctx->flag->load()) ? 1 : 0;
29+
}
30+
static std::string fetchUrl(const std::string& url, std::string& error, std::atomic<bool>* cancelFlag = nullptr) {
2531
LOG_INFO("fetchUrl: %s", url.c_str());
2632
std::string body;
2733
CURL* curl = curl_easy_init();
@@ -30,12 +36,16 @@ static std::string fetchUrl(const std::string& url, std::string& error) {
3036
curl_easy_setopt(curl, CURLOPT_WRITEFUNCTION, writeString);
3137
curl_easy_setopt(curl, CURLOPT_WRITEDATA, &body);
3238
curl_easy_setopt(curl, CURLOPT_FOLLOWLOCATION, 1L);
33-
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 30L);
34-
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 10L);
39+
curl_easy_setopt(curl, CURLOPT_TIMEOUT, 5L);
40+
curl_easy_setopt(curl, CURLOPT_CONNECTTIMEOUT, 3L);
3541
curl_easy_setopt(curl, CURLOPT_NOSIGNAL, 1L);
3642
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYPEER, 0L);
3743
curl_easy_setopt(curl, CURLOPT_SSL_VERIFYHOST, 0L);
3844
curl_easy_setopt(curl, CURLOPT_USERAGENT, "WiiUModStore/0.1");
45+
FetchCancelCtx ctx{ cancelFlag };
46+
curl_easy_setopt(curl, CURLOPT_XFERINFOFUNCTION, fetchProgress);
47+
curl_easy_setopt(curl, CURLOPT_XFERINFODATA, &ctx);
48+
curl_easy_setopt(curl, CURLOPT_NOPROGRESS, 0L);
3949
LOG_INFO("calling curl_easy_perform...");
4050
CURLcode res = curl_easy_perform(curl);
4151
LOG_INFO("curl returned: %d", res);
@@ -56,7 +66,7 @@ static std::string resolveUrl(const std::string& base, const std::string& path)
5666
return base.substr(0, slash + 1) + path;
5767
}
5868

59-
void RepoManager::fetch(const std::string& url) {
69+
void RepoManager::fetch(const std::string& url, std::atomic<bool>* cancelFlag) {
6070
m_lastError.clear();
6171
m_repo = {};
6272

@@ -67,7 +77,7 @@ void RepoManager::fetch(const std::string& url) {
6777
}
6878

6979
std::string err;
70-
std::string body = fetchUrl(url, err);
80+
std::string body = fetchUrl(url, err, cancelFlag);
7181
if (body.empty()) {
7282
m_lastError = "Network error: " + err;
7383
LOG_ERROR("RepoManager: %s", m_lastError.c_str());
@@ -101,7 +111,7 @@ void RepoManager::fetch(const std::string& url) {
101111
std::string gameUrl = resolveUrl(url, gamePath);
102112
LOG_INFO("RepoManager: fetching game from %s", gameUrl.c_str());
103113

104-
std::string gameBody = fetchUrl(gameUrl, err);
114+
std::string gameBody = fetchUrl(gameUrl, err, cancelFlag);
105115
if (gameBody.empty()) {
106116
LOG_WARN("RepoManager: failed to fetch %s: %s", gameUrl.c_str(), err.c_str());
107117
continue;

src/net/RepoManager.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
#include <optional>
55
#include <vector>
66
#include <cstdint>
7+
#include <atomic>
78

89
struct Mod {
910
std::string id;
@@ -46,7 +47,7 @@ class RepoManager {
4647
// Returns false if URL is invalid format
4748
static bool validateUrl(const std::string& url);
4849

49-
void fetch(const std::string& url);
50+
void fetch(const std::string& url, std::atomic<bool>* cancelFlag = nullptr);
5051

5152
const Repo& repo() const { return m_repo; }
5253
const std::string& lastError() const { return m_lastError; }

src/ui/MainLayout.cpp

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -25,10 +25,16 @@ static constexpr int GRID_TOP = 70;
2525
MainLayout::MainLayout(App* app) : Screen(app) {}
2626

2727
MainLayout::~MainLayout() {
28-
if (m_fetchThread.joinable()) m_fetchThread.detach();
28+
elog("~MainLayout: start");
29+
m_stopFetch = true;
30+
elog("~MainLayout: joining fetchThread");
31+
if (m_fetchThread.joinable()) m_fetchThread.join();
32+
elog("~MainLayout: join done");
33+
elog("~MainLayout: closing fonts");
2934
if (m_fontNormal) TTF_CloseFont(m_fontNormal);
3035
if (m_fontSmall) TTF_CloseFont(m_fontSmall);
3136
if (m_fontTiny) TTF_CloseFont(m_fontTiny);
37+
elog("~MainLayout: done");
3238
}
3339

3440
void MainLayout::onEnter() {
@@ -51,7 +57,7 @@ void MainLayout::onEnter() {
5157
if (m_stopFetch) break;
5258
LOG_INFO("Processing repo: %s", url.c_str());
5359
RepoManager rm;
54-
rm.fetch(url);
60+
rm.fetch(url, &m_stopFetch);
5561
{
5662
std::lock_guard<std::mutex> sl(m_repoMutex);
5763
m_repoStatus[url] = rm.lastError().empty() ? "OK" : rm.lastError();
@@ -68,6 +74,7 @@ void MainLayout::onEnter() {
6874
}
6975
}
7076

77+
if (m_stopFetch) return;
7178
std::lock_guard<std::mutex> lock(m_repoMutex);
7279
LOG_INFO("Fetch loop done, %zu total games", combined.games.size());
7380
m_repo = combined;

0 commit comments

Comments
 (0)