mirror of
https://github.com/libretro/RetroArch
synced 2025-04-09 21:45:45 +00:00
Fixed crash when the content is closed and the cheevos are still being loaded
This commit is contained in:
parent
a6f8013c24
commit
7b39da0848
@ -38,6 +38,10 @@
|
|||||||
#include "../menu/menu_entries.h"
|
#include "../menu/menu_entries.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
#include <rthreads/rthreads.h>
|
||||||
|
#endif
|
||||||
|
|
||||||
#include "badges.h"
|
#include "badges.h"
|
||||||
#include "cheevos.h"
|
#include "cheevos.h"
|
||||||
#include "var.h"
|
#include "var.h"
|
||||||
@ -219,6 +223,11 @@ typedef struct
|
|||||||
|
|
||||||
typedef struct
|
typedef struct
|
||||||
{
|
{
|
||||||
|
retro_task_t* task;
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
slock_t* task_lock;
|
||||||
|
#endif
|
||||||
|
|
||||||
cheevos_console_t console_id;
|
cheevos_console_t console_id;
|
||||||
bool core_supports;
|
bool core_supports;
|
||||||
bool addrs_patched;
|
bool addrs_patched;
|
||||||
@ -247,16 +256,24 @@ typedef struct
|
|||||||
|
|
||||||
static cheevos_locals_t cheevos_locals =
|
static cheevos_locals_t cheevos_locals =
|
||||||
{
|
{
|
||||||
|
/* task */ NULL,
|
||||||
|
#ifdef HAVE_THREADS
|
||||||
|
/* task_lock */ NULL,
|
||||||
|
#endif
|
||||||
|
|
||||||
/* console_id */ CHEEVOS_CONSOLE_NONE,
|
/* console_id */ CHEEVOS_CONSOLE_NONE,
|
||||||
/* core_supports */ true,
|
/* core_supports */ true,
|
||||||
/* addrs_patched */ false,
|
/* addrs_patched */ false,
|
||||||
/* add_buffer */ 0,
|
/* add_buffer */ 0,
|
||||||
/* add_hits */ 0,
|
/* add_hits */ 0,
|
||||||
|
|
||||||
/* core */ {NULL, 0},
|
/* core */ {NULL, 0},
|
||||||
/* unofficial */ {NULL, 0},
|
/* unofficial */ {NULL, 0},
|
||||||
/* leaderboards */ NULL,
|
/* leaderboards */ NULL,
|
||||||
/* lboard_count */ 0,
|
/* lboard_count */ 0,
|
||||||
|
|
||||||
/* token */ {0},
|
/* token */ {0},
|
||||||
|
|
||||||
{
|
{
|
||||||
/* meminfo[0] */ {NULL, 0, 0},
|
/* meminfo[0] */ {NULL, 0, 0},
|
||||||
/* meminfo[1] */ {NULL, 0, 0},
|
/* meminfo[1] */ {NULL, 0, 0},
|
||||||
@ -265,9 +282,17 @@ static cheevos_locals_t cheevos_locals =
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
bool cheevos_loaded = false;
|
bool cheevos_loaded = false;
|
||||||
int cheats_are_enabled = 0;
|
int cheats_are_enabled = 0;
|
||||||
int cheats_were_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.
|
Supporting functions.
|
||||||
@ -2462,18 +2487,28 @@ bool cheevos_apply_cheats(bool *data_bool)
|
|||||||
|
|
||||||
bool cheevos_unload(void)
|
bool cheevos_unload(void)
|
||||||
{
|
{
|
||||||
if (!cheevos_loaded)
|
CHEEVOS_LOCK(cheevos_locals.task_lock);
|
||||||
return false;
|
|
||||||
|
|
||||||
cheevos_free_cheevo_set(&cheevos_locals.core);
|
if (cheevos_locals.task)
|
||||||
cheevos_free_cheevo_set(&cheevos_locals.unofficial);
|
{
|
||||||
|
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.core.cheevos = NULL;
|
||||||
cheevos_locals.unofficial.cheevos = NULL;
|
cheevos_locals.unofficial.cheevos = NULL;
|
||||||
cheevos_locals.core.count = 0;
|
cheevos_locals.core.count = 0;
|
||||||
cheevos_locals.unofficial.count = 0;
|
cheevos_locals.unofficial.count = 0;
|
||||||
|
|
||||||
cheevos_loaded = 0;
|
cheevos_loaded = false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
@ -2695,7 +2730,6 @@ void cheevos_test(void)
|
|||||||
bool cheevos_set_cheats(void)
|
bool cheevos_set_cheats(void)
|
||||||
{
|
{
|
||||||
cheats_were_enabled = cheats_are_enabled;
|
cheats_were_enabled = cheats_are_enabled;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -2716,6 +2750,21 @@ cheevos_console_t cheevos_get_console(void)
|
|||||||
|
|
||||||
#include "coro.h"
|
#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
|
enum
|
||||||
{
|
{
|
||||||
/* Negative values because CORO_SUB generates positive values */
|
/* Negative values because CORO_SUB generates positive values */
|
||||||
@ -3719,13 +3768,20 @@ static void cheevos_task_handler(retro_task_t *task)
|
|||||||
if (!coro)
|
if (!coro)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (!cheevos_iterate(coro))
|
if (!cheevos_iterate(coro) || task_get_cancelled(task))
|
||||||
{
|
{
|
||||||
task_set_finished(task, true);
|
task_set_finished(task, true);
|
||||||
|
|
||||||
|
CHEEVOS_LOCK(cheevos_locals.task_lock);
|
||||||
|
cheevos_locals.task = NULL;
|
||||||
|
CHEEVOS_UNLOCK(cheevos_locals.task_lock);
|
||||||
|
|
||||||
if (coro->data)
|
if (coro->data)
|
||||||
free(coro->data);
|
free(coro->data);
|
||||||
|
|
||||||
if ((void*)coro->path)
|
if ((void*)coro->path)
|
||||||
free((void*)coro->path);
|
free((void*)coro->path);
|
||||||
|
|
||||||
free((void*)coro);
|
free((void*)coro);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -3736,7 +3792,7 @@ bool cheevos_load(const void *data)
|
|||||||
const struct retro_game_info *info = NULL;
|
const struct retro_game_info *info = NULL;
|
||||||
coro_t *coro = NULL;
|
coro_t *coro = NULL;
|
||||||
|
|
||||||
cheevos_loaded = 0;
|
cheevos_loaded = false;
|
||||||
|
|
||||||
if (!cheevos_locals.core_supports || !data)
|
if (!cheevos_locals.core_supports || !data)
|
||||||
return false;
|
return false;
|
||||||
@ -3795,6 +3851,18 @@ bool cheevos_load(const void *data)
|
|||||||
task->progress = 0;
|
task->progress = 0;
|
||||||
task->title = NULL;
|
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);
|
task_queue_push(task);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user