v2.9.4: Absturz beim Beenden behoben (Hintergrund-Threads, die noch auf den Server warten)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
Nico Meister
2026-10-18 22:47:36 +02:00
co-authored by Claude Opus 5.5
parent 52e0270c80
commit 9ffe07ff48
5 changed files with 29 additions and 12 deletions
+5 -3
View File
@@ -49,9 +49,11 @@ void admin_start(const char *server, u32 pid)
bool admin_is(void) { return isAdmin; } bool admin_is(void) { return isAdmin; }
void admin_finish(void) bool admin_finish(void)
{ {
if (!thread) return; if (!thread) return true;
if (R_SUCCEEDED(threadJoin(thread, 3ULL * 1000 * 1000 * 1000))) threadFree(thread); if (R_FAILED(threadJoin(thread, 15ULL * 1000 * 1000 * 1000))) return false; // läuft noch
threadFree(thread);
thread = NULL; thread = NULL;
return true;
} }
+1 -1
View File
@@ -6,4 +6,4 @@
void admin_start(const char *server, u32 pid); void admin_start(const char *server, u32 pid);
// Admin? (gemerkte Antwort, bis der Server geantwortet hat) // Admin? (gemerkte Antwort, bis der Server geantwortet hat)
bool admin_is(void); bool admin_is(void);
void admin_finish(void); bool admin_finish(void); // wartet höchstens 15 s, false = läuft noch
+14 -3
View File
@@ -681,11 +681,22 @@ int main(int argc, char **argv)
C3D_FrameEnd(0); C3D_FrameEnd(0);
} }
// Hintergrund-Threads, die noch auf den Server warten, dürfen ihren Speicher nicht verlieren: Sonst
// schreiben sie nach dem Freigeben hinein und Luma zeigt einen Absturz (z. B. beim Neustart nach "Nintendo").
ftpctl_stop(NULL, 0); ftpctl_stop(NULL, 0);
shopctl_exit(); shopctl_exit();
if (maintenanceThread) { threadJoin(maintenanceThread, U64_MAX); threadFree(maintenanceThread); } bool clean = true;
admin_finish(); if (maintenanceThread) {
update_finish(); if (R_SUCCEEDED(threadJoin(maintenanceThread, 20ULL * 1000 * 1000 * 1000))) threadFree(maintenanceThread);
else clean = false;
}
clean = admin_finish() && clean;
clean = update_finish() && clean;
if (!clean) {
// Hart beenden, ohne Speicher freizugeben (der Kernel räumt alles auf)
aptExit();
svcExitProcess();
}
frdswitch_exit(); frdswitch_exit();
nnid_exit(); nnid_exit();
httpcExit(); httpcExit();
+7 -4
View File
@@ -268,10 +268,13 @@ bool update_pending(void)
return state == UPD_AVAILABLE || state == UPD_DOWNLOADING || state == UPD_INSTALLED; return state == UPD_AVAILABLE || state == UPD_DOWNLOADING || state == UPD_INSTALLED;
} }
void update_finish(void) bool update_finish(void)
{ {
if (!thread) return; if (!thread) return true;
// Läuft der Download noch, nicht freigeben: Die App beendet sich ohnehin. // Läuft die Abfrage noch, nicht freigeben (sonst schreibt der Thread in freigegebenen Speicher).
if (R_SUCCEEDED(threadJoin(thread, 3ULL * 1000 * 1000 * 1000))) threadFree(thread); // false = läuft noch, die App muss sich hart beenden (main.c).
if (R_FAILED(threadJoin(thread, 15ULL * 1000 * 1000 * 1000))) return false;
threadFree(thread);
thread = NULL; thread = NULL;
return true;
} }
+2 -1
View File
@@ -21,7 +21,8 @@ void update_download(void);
bool update_pending(void); bool update_pending(void);
UpdateState update_state(void); UpdateState update_state(void);
const char *update_new_version(void); const char *update_new_version(void);
void update_finish(void); // Wartet auf den Hintergrund-Thread (höchstens 15 s). false = läuft noch.
bool update_finish(void);
// Laufender Download-Versuch (1-3) // Laufender Download-Versuch (1-3)
int update_attempt(void); int update_attempt(void);
// Beschreibung des letzten Fehlers (Schritt und Code) // Beschreibung des letzten Fehlers (Schritt und Code)