@@ -154,6 +154,7 @@ static uint32_t ClientReadMemory(uint32_t address, uint8_t* buffer, uint32_t num
154154static void ClientServerCall (const rc_api_request_t * request, rc_client_server_callback_t callback, void * callback_data,
155155 rc_client_t * client);
156156static rc_api_server_response_t MakeRCAPIServerResponse (s32 status_code, const std::vector<u8 >& data);
157+ static void WaitForHTTPRequestsWithYield (std::unique_lock<std::recursive_mutex>& lock);
157158
158159static void ClientEventHandler (const rc_client_event_t * event, rc_client_t * client);
159160static void HandleResetEvent (const rc_client_event_t * event);
@@ -829,6 +830,12 @@ rc_api_server_response_t Achievements::MakeRCAPIServerResponse(s32 status_code,
829830 };
830831}
831832
833+ void Achievements::WaitForHTTPRequestsWithYield (std::unique_lock<std::recursive_mutex>& lock)
834+ {
835+ DebugAssert (s_state.http_downloader );
836+ s_state.http_downloader ->WaitForAllRequestsWithYield ([&lock]() { lock.unlock (); }, [&lock]() { lock.lock (); });
837+ }
838+
832839void Achievements::IdleUpdate ()
833840{
834841 if (!IsActive ())
@@ -2096,11 +2103,6 @@ bool Achievements::DownloadGameIcons(ProgressCallback* progress, Error* error)
20962103
20972104 progress->FormatStatusText (TRANSLATE_FS (" Achievements" , " Fetching icon info for {} games..." ), game_ids.size ());
20982105
2099- // Create HTTP downloader
2100- std::unique_ptr<HTTPDownloader> http = HTTPDownloader::Create (Host::GetHTTPUserAgent (), error);
2101- if (!http)
2102- return false ;
2103-
21042106 // Fetch game titles (includes badge names) from RetroAchievements
21052107 const rc_api_fetch_game_titles_request_t titles_request = {
21062108 .game_ids = game_ids.data (),
@@ -2114,8 +2116,15 @@ bool Achievements::DownloadGameIcons(ProgressCallback* progress, Error* error)
21142116 return false ;
21152117 }
21162118
2119+ auto lock = GetLock ();
2120+ if (!IsActive ())
2121+ {
2122+ Error::SetStringView (error, TRANSLATE_SV (" Achievements" , " Achievements are not enabled." ));
2123+ return false ;
2124+ }
2125+
21172126 std::optional<rc_api_fetch_game_titles_response_t > titles_response;
2118- http ->CreatePostRequest (
2127+ s_state. http_downloader ->CreatePostRequest (
21192128 request.url , request.post_data ,
21202129 [&titles_response, error](s32 status_code, const Error&, const std::string&, HTTPDownloader::Request::Data data) {
21212130 const rc_api_server_response_t rr = MakeRCAPIServerResponse (status_code, data);
@@ -2129,7 +2138,7 @@ bool Achievements::DownloadGameIcons(ProgressCallback* progress, Error* error)
21292138 });
21302139
21312140 rc_api_destroy_request (&request);
2132- http-> WaitForAllRequests ( );
2141+ WaitForHTTPRequestsWithYield (lock );
21332142
21342143 if (!titles_response.has_value ())
21352144 return false ;
@@ -2164,27 +2173,27 @@ bool Achievements::DownloadGameIcons(ProgressCallback* progress, Error* error)
21642173 continue ;
21652174
21662175 badges_to_download++;
2167- http->CreateRequest (std::move (url), [path = std::move (path), progress](s32 status_code, const Error& http_error,
2168- const std::string&,
2169- HTTPDownloader::Request::Data data) {
2170- if (status_code == HTTPDownloader::HTTP_STATUS_OK)
2171- {
2172- INFO_LOG (" Writing badge to {}..." , Path::GetFileName (path));
2173-
2174- Error write_error;
2175- if (!FileSystem::FileExists (path.c_str ()) && !FileSystem::WriteBinaryFile (path.c_str (), data, &write_error))
2176+ s_state.http_downloader ->CreateRequest (
2177+ std::move (url), [path = std::move (path), progress](s32 status_code, const Error& http_error, const std::string&,
2178+ HTTPDownloader::Request::Data data) {
2179+ if (status_code == HTTPDownloader::HTTP_STATUS_OK)
21762180 {
2177- ERROR_LOG (" Failed to write badge to {}: {}" , Path::GetFileName (path), write_error.GetDescription ());
2178- FileSystem::DeleteFile (path.c_str ());
2181+ INFO_LOG (" Writing badge to {}..." , Path::GetFileName (path));
2182+
2183+ Error write_error;
2184+ if (!FileSystem::FileExists (path.c_str ()) && !FileSystem::WriteBinaryFile (path.c_str (), data, &write_error))
2185+ {
2186+ ERROR_LOG (" Failed to write badge to {}: {}" , Path::GetFileName (path), write_error.GetDescription ());
2187+ FileSystem::DeleteFile (path.c_str ());
2188+ }
2189+ }
2190+ else
2191+ {
2192+ ERROR_LOG (" Failed to download badge: HTTP {}: {}" , status_code, http_error.GetDescription ());
21792193 }
2180- }
2181- else
2182- {
2183- ERROR_LOG (" Failed to download badge: HTTP {}: {}" , status_code, http_error.GetDescription ());
2184- }
21852194
2186- progress->IncrementProgressValue ();
2187- });
2195+ progress->IncrementProgressValue ();
2196+ });
21882197 }
21892198
21902199 if (badges_to_download == 0 )
@@ -2195,7 +2204,7 @@ bool Achievements::DownloadGameIcons(ProgressCallback* progress, Error* error)
21952204
21962205 progress->SetProgressRange (badges_to_download);
21972206 progress->FormatStatusText (TRANSLATE_FS (" Achievements" , " Downloading {} game badges..." ), badges_to_download);
2198- http-> WaitForAllRequests ( );
2207+ WaitForHTTPRequestsWithYield (lock );
21992208 return true ;
22002209}
22012210
0 commit comments