mirror of
https://github.com/libretro/RetroArch
synced 2025-03-29 22:20:21 +00:00
Fixed crash when the content is closed and the cheevos are still being loaded
This commit is contained in:
parent
fb257eb21e
commit
e54da03ddc
@ -38,6 +38,10 @@
|
||||
#include "../menu/menu_entries.h"
|
||||
#endif
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#include <rthreads/rthreads.h>
|
||||
#endif
|
||||
|
||||
#include "badges.h"
|
||||
#include "cheevos.h"
|
||||
#include "var.h"
|
||||
@ -219,6 +223,11 @@ typedef struct
|
||||
|
||||
typedef struct
|
||||
{
|
||||
retro_task_t* task;
|
||||
#ifdef HAVE_THREADS
|
||||
slock_t* task_lock;
|
||||
#endif
|
||||
|
||||
cheevos_console_t console_id;
|
||||
bool core_supports;
|
||||
bool addrs_patched;
|
||||
@ -247,16 +256,24 @@ typedef struct
|
||||
|
||||
static cheevos_locals_t cheevos_locals =
|
||||
{
|
||||
/* task */ NULL,
|
||||
#ifdef HAVE_THREADS
|
||||
/* task_lock */ NULL,
|
||||
#endif
|
||||
|
||||
/* console_id */ CHEEVOS_CONSOLE_NONE,
|
||||
/* core_supports */ true,
|
||||
/* addrs_patched */ false,
|
||||
/* add_buffer */ 0,
|
||||
/* add_hits */ 0,
|
||||
|
||||
/* core */ {NULL, 0},
|
||||
/* unofficial */ {NULL, 0},
|
||||
/* leaderboards */ NULL,
|
||||
/* lboard_count */ 0,
|
||||
|
||||
/* token */ {0},
|
||||
|
||||
{
|
||||
/* meminfo[0] */ {NULL, 0, 0},
|
||||
/* meminfo[1] */ {NULL, 0, 0},
|
||||
@ -265,9 +282,17 @@ static cheevos_locals_t cheevos_locals =
|
||||
}
|
||||
};
|
||||
|
||||
bool cheevos_loaded = false;
|
||||
int cheats_are_enabled = 0;
|
||||
int cheats_were_enabled = 0;
|
||||
bool cheevos_loaded = false;
|
||||
int cheats_are_enabled = 0;
|
||||
int cheats_were_enabled = 0;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
#define CHEEVOS_LOCK(l) do { slock_lock(l); } while (0)
|
||||
#define CHEEVOS_UNLOCK(l) do { slock_unlock(l); } while (0)
|
||||
#else
|
||||
#define CHEEVOS_LOCK(l)
|
||||
#define CHEEVOS_UNLOCK(l)
|
||||
#endif
|
||||
|
||||
/*****************************************************************************
|
||||
Supporting functions.
|
||||
@ -2462,18 +2487,28 @@ bool cheevos_apply_cheats(bool *data_bool)
|
||||
|
||||
bool cheevos_unload(void)
|
||||
{
|
||||
if (!cheevos_loaded)
|
||||
return false;
|
||||
CHEEVOS_LOCK(cheevos_locals.task_lock);
|
||||
|
||||
cheevos_free_cheevo_set(&cheevos_locals.core);
|
||||
cheevos_free_cheevo_set(&cheevos_locals.unofficial);
|
||||
if (cheevos_locals.task)
|
||||
{
|
||||
task_queue_cancel_task(cheevos_locals.task);
|
||||
while (cheevos_locals.task) /* nothing */;
|
||||
}
|
||||
|
||||
if (cheevos_loaded)
|
||||
{
|
||||
cheevos_free_cheevo_set(&cheevos_locals.core);
|
||||
cheevos_free_cheevo_set(&cheevos_locals.unofficial);
|
||||
}
|
||||
|
||||
CHEEVOS_UNLOCK(cheevos_locals.task_lock);
|
||||
|
||||
cheevos_locals.core.cheevos = NULL;
|
||||
cheevos_locals.unofficial.cheevos = NULL;
|
||||
cheevos_locals.core.count = 0;
|
||||
cheevos_locals.unofficial.count = 0;
|
||||
|
||||
cheevos_loaded = 0;
|
||||
cheevos_loaded = false;
|
||||
|
||||
return true;
|
||||
}
|
||||
@ -2695,7 +2730,6 @@ void cheevos_test(void)
|
||||
bool cheevos_set_cheats(void)
|
||||
{
|
||||
cheats_were_enabled = cheats_are_enabled;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -2716,6 +2750,21 @@ cheevos_console_t cheevos_get_console(void)
|
||||
|
||||
#include "coro.h"
|
||||
|
||||
/* Uncomment the following two lines to debug cheevos_iterate, this will
|
||||
* disable the coroutine yielding.
|
||||
*
|
||||
* The code is very easy to understand. It's meant to be like BASIC:
|
||||
* CORO_GOTO will jump execution to another label, CORO_GOSUB will
|
||||
* call another label, and CORO_RET will return from a CORO_GOSUB.
|
||||
*
|
||||
* This coroutine code is inspired in a very old pure C implementation
|
||||
* that runs everywhere:
|
||||
*
|
||||
* https://www.chiark.greenend.org.uk/~sgtatham/coroutines.html
|
||||
*/
|
||||
/*#undef CORO_YIELD
|
||||
#define CORO_YIELD()*/
|
||||
|
||||
enum
|
||||
{
|
||||
/* Negative values because CORO_SUB generates positive values */
|
||||
@ -3719,13 +3768,20 @@ static void cheevos_task_handler(retro_task_t *task)
|
||||
if (!coro)
|
||||
return;
|
||||
|
||||
if (!cheevos_iterate(coro))
|
||||
if (!cheevos_iterate(coro) || task_get_cancelled(task))
|
||||
{
|
||||
task_set_finished(task, true);
|
||||
|
||||
CHEEVOS_LOCK(cheevos_locals.task_lock);
|
||||
cheevos_locals.task = NULL;
|
||||
CHEEVOS_UNLOCK(cheevos_locals.task_lock);
|
||||
|
||||
if (coro->data)
|
||||
free(coro->data);
|
||||
|
||||
if ((void*)coro->path)
|
||||
free((void*)coro->path);
|
||||
|
||||
free((void*)coro);
|
||||
}
|
||||
}
|
||||
@ -3736,7 +3792,7 @@ bool cheevos_load(const void *data)
|
||||
const struct retro_game_info *info = NULL;
|
||||
coro_t *coro = NULL;
|
||||
|
||||
cheevos_loaded = 0;
|
||||
cheevos_loaded = false;
|
||||
|
||||
if (!cheevos_locals.core_supports || !data)
|
||||
return false;
|
||||
@ -3795,6 +3851,18 @@ bool cheevos_load(const void *data)
|
||||
task->progress = 0;
|
||||
task->title = NULL;
|
||||
|
||||
#ifdef HAVE_THREADS
|
||||
if (cheevos_locals.task_lock == NULL)
|
||||
{
|
||||
cheevos_locals.task_lock = slock_new();
|
||||
}
|
||||
#endif
|
||||
|
||||
CHEEVOS_LOCK(cheevos_locals.task_lock);
|
||||
cheevos_locals.task = task;
|
||||
CHEEVOS_UNLOCK(cheevos_locals.task_lock);
|
||||
|
||||
task_queue_push(task);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user