mirror of
https://github.com/libretro/RetroArch
synced 2025-04-01 13:20:43 +00:00
fix a whole bunch of memory leaks
This commit is contained in:
parent
a09e110d24
commit
e0b75ec3fb
@ -209,8 +209,10 @@ void task_queue_retrieve(task_retriever_data_t *data);
|
||||
void task_queue_check(void);
|
||||
|
||||
/* Pushes a task
|
||||
* The task will start as soon as possible. */
|
||||
void task_queue_push(retro_task_t *task);
|
||||
* The task will start as soon as possible.
|
||||
* If a second blocking task is attempted, false will be returned
|
||||
* and the task will be ignored. */
|
||||
bool task_queue_push(retro_task_t *task);
|
||||
|
||||
/* Blocks until all tasks have finished
|
||||
* will return early if cond is not NULL
|
||||
|
@ -610,7 +610,7 @@ void task_queue_check(void)
|
||||
impl_current->gather();
|
||||
}
|
||||
|
||||
void task_queue_push(retro_task_t *task)
|
||||
bool task_queue_push(retro_task_t *task)
|
||||
{
|
||||
/* Ignore this task if a related one is already running */
|
||||
if (task->type == TASK_TYPE_BLOCKING)
|
||||
@ -634,12 +634,14 @@ void task_queue_push(retro_task_t *task)
|
||||
|
||||
/* skip this task, user must try again later */
|
||||
if (found)
|
||||
return;
|
||||
return false;
|
||||
}
|
||||
|
||||
/* The lack of NULL checks in the following functions
|
||||
* is proposital to ensure correct control flow by the users. */
|
||||
impl_current->push_running(task);
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void task_queue_wait(retro_task_condition_fn_t cond, void* data)
|
||||
|
@ -511,6 +511,8 @@ static void undo_save_state_cb(retro_task_t *task,
|
||||
void *task_data,
|
||||
void *user_data, const char *error)
|
||||
{
|
||||
save_task_state_t *state = (save_task_state_t*)task_data;
|
||||
|
||||
/* Wipe the save file buffer as it's intended to be one use only */
|
||||
undo_save_buf.path[0] = '\0';
|
||||
undo_save_buf.size = 0;
|
||||
@ -519,6 +521,8 @@ static void undo_save_state_cb(retro_task_t *task,
|
||||
free(undo_save_buf.data);
|
||||
undo_save_buf.data = NULL;
|
||||
}
|
||||
|
||||
free(state);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -563,6 +567,9 @@ void* get_serialized_data(const char *path, size_t serial_size)
|
||||
bool ret = false;
|
||||
void *data = NULL;
|
||||
|
||||
if (!serial_size)
|
||||
return NULL;
|
||||
|
||||
data = malloc(serial_size);
|
||||
|
||||
if (!data)
|
||||
@ -576,11 +583,13 @@ void* get_serialized_data(const char *path, size_t serial_size)
|
||||
serial_info.data = data;
|
||||
serial_info.size = serial_size;
|
||||
ret = core_serialize(&serial_info);
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
free(data);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
@ -1054,6 +1063,7 @@ static void save_state_cb(retro_task_t *task,
|
||||
take_screenshot(path, true, state->has_valid_framebuffer, false, true);
|
||||
|
||||
free(path);
|
||||
free(state);
|
||||
}
|
||||
|
||||
/**
|
||||
@ -1089,7 +1099,16 @@ static void task_push_save_state(const char *path, void *data, size_t size, bool
|
||||
task->title = strdup(msg_hash_to_str(MSG_SAVING_STATE));
|
||||
task->mute = state->mute;
|
||||
|
||||
task_queue_push(task);
|
||||
if (!task_queue_push(task))
|
||||
{
|
||||
/* Another blocking task is already active. */
|
||||
if (data)
|
||||
free(data);
|
||||
if (task->title)
|
||||
task_free_title(task);
|
||||
free(task);
|
||||
free(state);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@ -1099,8 +1118,12 @@ error:
|
||||
if (state)
|
||||
free(state);
|
||||
if (task)
|
||||
{
|
||||
if (task->title)
|
||||
task_free_title(task);
|
||||
free(task);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* content_load_and_save_state_cb:
|
||||
@ -1163,7 +1186,16 @@ static void task_push_load_and_save_state(const char *path, void *data,
|
||||
task->title = strdup(msg_hash_to_str(MSG_LOADING_STATE));
|
||||
task->mute = state->mute;
|
||||
|
||||
task_queue_push(task);
|
||||
if (!task_queue_push(task))
|
||||
{
|
||||
/* Another blocking task is already active. */
|
||||
if (data)
|
||||
free(data);
|
||||
if (task->title)
|
||||
task_free_title(task);
|
||||
free(task);
|
||||
free(state);
|
||||
}
|
||||
|
||||
return;
|
||||
|
||||
@ -1214,7 +1246,6 @@ bool content_save_state(const char *path, bool save_to_disk, bool autosave)
|
||||
msg_hash_to_str(MSG_STATE_SIZE),
|
||||
(int)info.size,
|
||||
msg_hash_to_str(MSG_BYTES));
|
||||
|
||||
}
|
||||
|
||||
if (save_to_disk)
|
||||
|
@ -49,6 +49,7 @@
|
||||
#include "../retroarch.h"
|
||||
#include "../paths.h"
|
||||
#include "../msg_hash.h"
|
||||
#include "../verbosity.h"
|
||||
|
||||
#include "../gfx/video_driver.h"
|
||||
|
||||
@ -143,6 +144,9 @@ static void task_screenshot_handler(retro_task_t *task)
|
||||
{
|
||||
task_set_finished(task, true);
|
||||
|
||||
if (task->title)
|
||||
task_free_title(task);
|
||||
|
||||
if (state->userbuf)
|
||||
free(state->userbuf);
|
||||
|
||||
@ -173,6 +177,9 @@ static void task_screenshot_handler(retro_task_t *task)
|
||||
runloop_msg_queue_push(msg, 1, state->is_paused ? 1 : 180, true, NULL, MESSAGE_QUEUE_ICON_DEFAULT, MESSAGE_QUEUE_CATEGORY_INFO);
|
||||
free(msg);
|
||||
}
|
||||
|
||||
if (task->title)
|
||||
task_free_title(task);
|
||||
}
|
||||
|
||||
/* Take frame bottom-up. */
|
||||
@ -191,18 +198,20 @@ static bool screenshot_dump(
|
||||
char screenshot_path[PATH_MAX_LENGTH];
|
||||
uint8_t *buf = NULL;
|
||||
settings_t *settings = config_get_ptr();
|
||||
retro_task_t *task = task_init();
|
||||
screenshot_task_state_t *state = (screenshot_task_state_t*)
|
||||
calloc(1, sizeof(*state));
|
||||
retro_task_t *task;
|
||||
screenshot_task_state_t *state;
|
||||
const char *screenshot_dir = settings->paths.directory_screenshot;
|
||||
struct retro_system_info system_info;
|
||||
|
||||
state->shotname[0] = '\0';
|
||||
screenshot_path[0] = '\0';
|
||||
|
||||
if (!core_get_system_info(&system_info))
|
||||
return false;
|
||||
|
||||
task = task_init();
|
||||
state = (screenshot_task_state_t*)calloc(1, sizeof(*state));
|
||||
state->shotname[0] = '\0';
|
||||
|
||||
/* If fullpath is true, name_base already contains a static path + filename to save the screenshot to. */
|
||||
if (fullpath)
|
||||
strlcpy(state->filename, name_base, sizeof(state->filename));
|
||||
@ -282,10 +291,28 @@ static bool screenshot_dump(
|
||||
if (!savestate)
|
||||
task->title = strdup(msg_hash_to_str(MSG_TAKING_SCREENSHOT));
|
||||
|
||||
task_queue_push(task);
|
||||
if (!task_queue_push(task))
|
||||
{
|
||||
/* There is already a blocking task going on */
|
||||
if (task->title)
|
||||
task_free_title(task);
|
||||
|
||||
free(task);
|
||||
|
||||
if (state->out_buffer)
|
||||
free(state->out_buffer);
|
||||
|
||||
free(state);
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if (task)
|
||||
free(task);
|
||||
return screenshot_dump_direct(state);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user