mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2025-04-16 06:11:15 +00:00
[util] Fix a pile of memory leaks
Some were actually legitimate (in that they'd cause problems in a long running game).
This commit is contained in:
parent
9ad4f57348
commit
13f8f2b66b
8 changed files with 175 additions and 58 deletions
|
@ -40,6 +40,7 @@
|
|||
#include "QF/cbuf.h"
|
||||
#include "QF/cmd.h"
|
||||
#include "QF/idparse.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
typedef struct idbuf_s {
|
||||
dstring_t *buf, *line;
|
||||
|
@ -253,3 +254,17 @@ VISIBLE cbuf_interpreter_t id_interp = {
|
|||
COM_execute_sets,
|
||||
NULL
|
||||
};
|
||||
|
||||
static void
|
||||
idparse_shutdown (void *data)
|
||||
{
|
||||
if (_com_token) {
|
||||
dstring_delete (_com_token);
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((constructor))
|
||||
idparse_init (void)
|
||||
{
|
||||
Sys_RegisterShutdown (idparse_shutdown, 0);
|
||||
}
|
||||
|
|
|
@ -242,3 +242,16 @@ COM_ExecConfig (cbuf_t *cbuf, int skip_quakerc)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qargs_shutdown (void *data)
|
||||
{
|
||||
free (largv);
|
||||
free ((char *) com_cmdline);
|
||||
}
|
||||
|
||||
static void __attribute__((constructor))
|
||||
qargs_init (void)
|
||||
{
|
||||
Sys_RegisterShutdown (qargs_shutdown, 0);
|
||||
}
|
||||
|
|
|
@ -571,6 +571,42 @@ qfs_process_path (const char *path, const char *gamedir)
|
|||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qfs_free_gamedir (void)
|
||||
{
|
||||
if (qfs_gamedir) {
|
||||
if (qfs_gamedir->name)
|
||||
free ((char *)qfs_gamedir->name);
|
||||
if (qfs_gamedir->gamedir)
|
||||
free ((char *)qfs_gamedir->gamedir);
|
||||
if (qfs_gamedir->path)
|
||||
free ((char *)qfs_gamedir->path);
|
||||
if (qfs_gamedir->gamecode)
|
||||
free ((char *)qfs_gamedir->gamecode);
|
||||
if (qfs_gamedir->hudtype)
|
||||
free ((char *)qfs_gamedir->hudtype);
|
||||
if (qfs_gamedir->dir.def)
|
||||
free ((char *)qfs_gamedir->dir.def);
|
||||
if (qfs_gamedir->dir.skins)
|
||||
free ((char *)qfs_gamedir->dir.skins);
|
||||
if (qfs_gamedir->dir.models)
|
||||
free ((char *)qfs_gamedir->dir.models);
|
||||
if (qfs_gamedir->dir.sound)
|
||||
free ((char *)qfs_gamedir->dir.sound);
|
||||
if (qfs_gamedir->dir.maps)
|
||||
free ((char *)qfs_gamedir->dir.maps);
|
||||
if (qfs_gamedir->dir.shots)
|
||||
free ((char *)qfs_gamedir->dir.shots);
|
||||
free (qfs_gamedir);
|
||||
}
|
||||
|
||||
while (qfs_vpaths) {
|
||||
vpath_t *next = qfs_vpaths->next;
|
||||
delete_vpath (qfs_vpaths);
|
||||
qfs_vpaths = next;
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
qfs_build_gamedir (const char **list)
|
||||
{
|
||||
|
@ -584,33 +620,7 @@ qfs_build_gamedir (const char **list)
|
|||
|
||||
qfs_set_var (vars, "game", qfs_game);
|
||||
|
||||
if (qfs_gamedir) {
|
||||
if (qfs_gamedir->name)
|
||||
free ((char *)qfs_gamedir->name);
|
||||
if (qfs_gamedir->gamedir)
|
||||
free ((char *)qfs_gamedir->gamedir);
|
||||
if (qfs_gamedir->path)
|
||||
free ((char *)qfs_gamedir->path);
|
||||
if (qfs_gamedir->gamecode)
|
||||
free ((char *)qfs_gamedir->gamecode);
|
||||
if (qfs_gamedir->dir.def)
|
||||
free ((char *)qfs_gamedir->dir.def);
|
||||
if (qfs_gamedir->dir.skins)
|
||||
free ((char *)qfs_gamedir->dir.skins);
|
||||
if (qfs_gamedir->dir.models)
|
||||
free ((char *)qfs_gamedir->dir.models);
|
||||
if (qfs_gamedir->dir.sound)
|
||||
free ((char *)qfs_gamedir->dir.sound);
|
||||
if (qfs_gamedir->dir.maps)
|
||||
free ((char *)qfs_gamedir->dir.maps);
|
||||
free (qfs_gamedir);
|
||||
}
|
||||
|
||||
while (qfs_vpaths) {
|
||||
vpath_t *next = qfs_vpaths->next;
|
||||
delete_vpath (qfs_vpaths);
|
||||
qfs_vpaths = next;
|
||||
}
|
||||
qfs_free_gamedir ();
|
||||
|
||||
for (j = 0; list[j]; j++)
|
||||
;
|
||||
|
@ -829,13 +839,10 @@ QFS_WriteFile (const char *filename, const void *data, int len)
|
|||
Qclose (f);
|
||||
}
|
||||
|
||||
static int_findfile_t *
|
||||
qfs_findfile_search (const vpath_t *vpath, const searchpath_t *sp,
|
||||
const char **fnames)
|
||||
static int_findfile_t found;
|
||||
static void
|
||||
clear_findfile (void)
|
||||
{
|
||||
static int_findfile_t found;
|
||||
const char **fn;
|
||||
|
||||
found.ff.vpath = 0;
|
||||
found.ff.in_pak = false;
|
||||
found.pack = 0;
|
||||
|
@ -849,6 +856,15 @@ qfs_findfile_search (const vpath_t *vpath, const searchpath_t *sp,
|
|||
free ((char *) found.path);
|
||||
found.path = 0;
|
||||
}
|
||||
}
|
||||
|
||||
static int_findfile_t *
|
||||
qfs_findfile_search (const vpath_t *vpath, const searchpath_t *sp,
|
||||
const char **fnames)
|
||||
{
|
||||
const char **fn;
|
||||
|
||||
clear_findfile ();
|
||||
// is the element a pak file?
|
||||
if (sp->pack) {
|
||||
dpackfile_t *packfile = 0;
|
||||
|
@ -1456,11 +1472,13 @@ qfs_path_cvar (void *data, const cvar_t *cvar)
|
|||
static void
|
||||
qfs_shutdown (void *data)
|
||||
{
|
||||
while (qfs_vpaths) {
|
||||
vpath_t *next = qfs_vpaths->next;
|
||||
delete_vpath (qfs_vpaths);
|
||||
qfs_vpaths = next;
|
||||
}
|
||||
clear_findfile ();
|
||||
qfs_free_gamedir ();
|
||||
PL_Free (qfs_gd_plist);
|
||||
free ((char *) qfs_userpath);
|
||||
free (gamedir_callbacks);
|
||||
ALLOC_FREE_BLOCKS (vpaths);
|
||||
ALLOC_FREE_BLOCKS (searchpaths);
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
|
|
|
@ -213,3 +213,16 @@ Segtext_Find (const segtext_t *st, const char *tag)
|
|||
return chunk->text;
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void
|
||||
segtext_shutdown (void *data)
|
||||
{
|
||||
ALLOC_FREE_BLOCKS (chunks);
|
||||
ALLOC_FREE_BLOCKS (texts);
|
||||
}
|
||||
|
||||
static void __attribute__((constructor))
|
||||
segtext_init (void)
|
||||
{
|
||||
Sys_RegisterShutdown (segtext_shutdown, 0);
|
||||
}
|
||||
|
|
|
@ -721,3 +721,16 @@ set_as_string (const set_t *set)
|
|||
dstring_clearstr (str);
|
||||
return set_to_dstring_r (&static_set_pool, str, set);
|
||||
}
|
||||
|
||||
static void
|
||||
set_shutdown (void *data)
|
||||
{
|
||||
ALLOC_FREE_BLOCKS (static_set_pool.set);
|
||||
ALLOC_FREE_BLOCKS (static_set_pool.set_iter);
|
||||
}
|
||||
|
||||
static void __attribute__((constructor))
|
||||
set_init (void)
|
||||
{
|
||||
Sys_RegisterShutdown (set_shutdown, 0);
|
||||
}
|
||||
|
|
|
@ -536,22 +536,6 @@ Sys_Init_Cvars (void)
|
|||
Cvar_Register (&sys_sleep_cvar, 0, 0);
|
||||
}
|
||||
|
||||
void
|
||||
Sys_Shutdown (void)
|
||||
{
|
||||
shutdown_list_t *t;
|
||||
|
||||
while (shutdown_list) {
|
||||
void (*func) (void *) = shutdown_list->func;
|
||||
void *data = shutdown_list->data;
|
||||
t = shutdown_list;
|
||||
shutdown_list = shutdown_list->next;
|
||||
free (t);
|
||||
|
||||
func (data);
|
||||
}
|
||||
}
|
||||
|
||||
VISIBLE void
|
||||
Sys_Quit (void)
|
||||
{
|
||||
|
@ -1231,3 +1215,45 @@ Sys_UniqueFile (dstring_t *name, const char *prefix, const char *suffix,
|
|||
seq++;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
Sys_Shutdown (void)
|
||||
{
|
||||
shutdown_list_t *t;
|
||||
|
||||
while (shutdown_list) {
|
||||
void (*func) (void *) = shutdown_list->func;
|
||||
void *data = shutdown_list->data;
|
||||
t = shutdown_list;
|
||||
shutdown_list = shutdown_list->next;
|
||||
free (t);
|
||||
|
||||
func (data);
|
||||
}
|
||||
while (free_sh) {
|
||||
__auto_type t = free_sh->next;
|
||||
free (free_sh);
|
||||
free_sh = t;
|
||||
}
|
||||
while (sh_stack) {
|
||||
__auto_type t = sh_stack->next;
|
||||
free (sh_stack);
|
||||
sh_stack = t;
|
||||
}
|
||||
while (error_handler_freelist) {
|
||||
__auto_type t = error_handler_freelist->next;
|
||||
free (error_handler_freelist);
|
||||
error_handler_freelist = t;
|
||||
}
|
||||
while (error_handler) {
|
||||
__auto_type t = error_handler->next;
|
||||
free (error_handler);
|
||||
error_handler = t;
|
||||
}
|
||||
if (sys_print_msg) {
|
||||
dstring_delete (sys_print_msg);
|
||||
}
|
||||
if (sys_debuglog_data) {
|
||||
dstring_delete (sys_debuglog_data);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@
|
|||
#include <stdio.h>
|
||||
|
||||
#include "QF/segtext.h"
|
||||
#include "QF/sys.h"
|
||||
|
||||
static const char *test_string =
|
||||
"blah\n"
|
||||
|
@ -83,5 +84,7 @@ main (int argc, const char **argv)
|
|||
res = 1;
|
||||
}
|
||||
}
|
||||
Segtext_delete (st);
|
||||
Sys_Shutdown ();
|
||||
return res;
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@
|
|||
#include <stdarg.h>
|
||||
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/sys.h"
|
||||
#include "QF/va.h"
|
||||
|
||||
struct va_ctx_s {
|
||||
|
@ -46,6 +47,8 @@ struct va_ctx_s {
|
|||
int str_index;
|
||||
};
|
||||
|
||||
static va_ctx_t *default_va_ctx;
|
||||
|
||||
VISIBLE va_ctx_t *
|
||||
va_create_context (int buffers)
|
||||
{
|
||||
|
@ -74,15 +77,14 @@ va_destroy_context (va_ctx_t *ctx)
|
|||
VISIBLE const char *
|
||||
va (va_ctx_t *ctx, const char *fmt, ...)
|
||||
{
|
||||
static va_ctx_t *_ctx;
|
||||
va_list args;
|
||||
dstring_t *dstr;
|
||||
|
||||
if (!ctx) {
|
||||
if (!_ctx) {
|
||||
_ctx = va_create_context (4);
|
||||
if (!default_va_ctx) {
|
||||
default_va_ctx = va_create_context (4);
|
||||
}
|
||||
ctx = _ctx;
|
||||
ctx = default_va_ctx;
|
||||
}
|
||||
dstr = ctx->strings[ctx->str_index++ % ctx->num_strings];
|
||||
|
||||
|
@ -107,3 +109,17 @@ nva (const char *fmt, ...)
|
|||
|
||||
return dstring_freeze (string);
|
||||
}
|
||||
|
||||
static void
|
||||
va_shutdown (void *data)
|
||||
{
|
||||
if (default_va_ctx) {
|
||||
va_destroy_context (default_va_ctx);
|
||||
}
|
||||
}
|
||||
|
||||
static void __attribute__((constructor))
|
||||
va_init (void)
|
||||
{
|
||||
Sys_RegisterShutdown (va_shutdown, 0);
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue