fix a whole bunch of memory leaks

This commit is contained in:
Brad Parker 2019-03-01 12:05:14 -05:00
parent a09e110d24
commit e0b75ec3fb
4 changed files with 88 additions and 26 deletions

View File

@ -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

View File

@ -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)

View File

@ -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,12 +583,14 @@ 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 )
if (!ret)
{
free(data) ;
return NULL ;
free(data);
return NULL;
}
return data ;
return data;
}
/**
@ -607,7 +616,7 @@ static void task_save_handler(retro_task_t *task)
}
if (!state->data)
state->data = get_serialized_data(state->path, state->size) ;
state->data = get_serialized_data(state->path, state->size);
remaining = MIN(state->size - state->written, SAVE_STATE_CHUNK);
@ -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,7 +1118,11 @@ error:
if (state)
free(state);
if (task)
{
if (task->title)
task_free_title(task);
free(task);
}
}
/**
@ -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;
@ -1194,13 +1226,13 @@ bool content_save_state(const char *path, bool save_to_disk, bool autosave)
if (info.size == 0)
return false;
if ( !save_state_in_background )
if (!save_state_in_background)
{
RARCH_LOG("%s: \"%s\".\n",
msg_hash_to_str(MSG_SAVING_STATE),
path);
data = get_serialized_data(path, info.size) ;
data = get_serialized_data(path, info.size);
if (!data)
{
@ -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)
@ -1234,15 +1265,15 @@ bool content_save_state(const char *path, bool save_to_disk, bool autosave)
}
else
{
if ( data == NULL )
data = get_serialized_data(path, info.size) ;
if (data == NULL)
data = get_serialized_data(path, info.size);
if ( data == NULL )
if (data == NULL)
{
RARCH_ERR("%s \"%s\".\n",
msg_hash_to_str(MSG_FAILED_TO_SAVE_STATE_TO),
path);
return false ;
return false;
}
/* save_to_disk is false, which means we are saving the state
in undo_load_buf to allow content_undo_load_state() to restore it */
@ -1528,7 +1559,7 @@ bool event_save_files(void)
{
unsigned i;
cheat_manager_save_game_specific_cheats() ;
cheat_manager_save_game_specific_cheats();
if (!task_save_files ||
!rarch_ctl(RARCH_CTL_IS_SRAM_USED, NULL))
return false;
@ -1594,5 +1625,5 @@ void *savefile_ptr_get(void)
void set_save_state_in_background(bool state)
{
save_state_in_background = state ;
save_state_in_background = state;
}

View File

@ -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,17 +198,19 @@ 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;
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)
@ -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;
}