Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Store: Fix race condition causing crashes if looking at another game before an icon finishes downloading #18185

Merged
merged 1 commit into from
Sep 20, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion Common/UI/IconCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -228,7 +228,7 @@ bool IconCache::MarkPending(const std::string &key) {
return true;
}

void IconCache::Cancel(const std::string &key) {
void IconCache::CancelPending(const std::string &key) {
std::unique_lock<std::mutex> lock(lock_);
pending_.erase(key);
}
Expand Down Expand Up @@ -266,6 +266,7 @@ Draw::Texture *IconCache::BindIconTexture(UIContext *context, const std::string
return nullptr;
}

// TODO: Cut down on how long we're holding this lock here.
std::unique_lock<std::mutex> lock(lock_);
auto iter = cache_.find(key);
if (iter == cache_.end()) {
Expand Down
2 changes: 1 addition & 1 deletion Common/UI/IconCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class IconCache {

// It's okay to call these from any thread.
bool MarkPending(const std::string &key); // returns false if already pending or loaded
void Cancel(const std::string &key);
void CancelPending(const std::string &key);
bool InsertIcon(const std::string &key, IconFormat format, std::string &&pngData);
bool GetDimensions(const std::string &key, int *width, int *height);
bool Contains(const std::string &key);
Expand Down
2 changes: 2 additions & 0 deletions Core/HW/SasAudio.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -396,6 +396,8 @@ void SasInstance::GetDebugText(char *text, size_t bufsize) {
indicator = " (BAD!)";
}
break;
default:
break;
}
p += snprintf(p, sizeof(voiceBuf) - (p - voiceBuf), " %d: Pitch %04x L/R,FX: %d,%d|%d,%d VAG: %08x:%d:%08x%s Height:%d%%\n", i,
voices[i].pitch, voices[i].volumeLeft, voices[i].volumeRight, voices[i].effectLeft, voices[i].effectRight,
Expand Down
13 changes: 8 additions & 5 deletions UI/Store.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -63,25 +63,28 @@ class HttpImageFileView : public UI::View {

if (useIconCache && g_iconCache.MarkPending(path_)) {
const char *acceptMime = "image/png, image/jpeg, image/*; q=0.9, */*; q=0.8";
requestManager_->StartDownloadWithCallback(path_, Path(), http::ProgressBarMode::DELAYED, [&](http::Request &download) {
requestManager_->StartDownloadWithCallback(path_, Path(), http::ProgressBarMode::DELAYED, [](http::Request &download) {
// Can't touch 'this' in this function! Don't use captures!
std::string path = download.url();
if (download.ResultCode() == 200) {
std::string data;
download.buffer().TakeAll(&data);
if (!data.empty()) {
g_iconCache.InsertIcon(path_, IconFormat::PNG, std::move(data));
g_iconCache.InsertIcon(path, IconFormat::PNG, std::move(data));
} else {
g_iconCache.Cancel(path_);
g_iconCache.CancelPending(path);
}
} else {
g_iconCache.Cancel(path_);
g_iconCache.CancelPending(path);
}
}, acceptMime);
}
}

~HttpImageFileView() {
if (download_)
if (download_) {
download_->Cancel();
}
}

void GetContentDimensions(const UIContext &dc, float &w, float &h) const override;
Expand Down