mirror of
https://git.code.sf.net/p/quake/quakeforge
synced 2024-11-10 07:11:41 +00:00
[ruamoko] Plug yet more memory leaks
Some of them, especially in rua_obj, were quite legitimate and even a problem for thread-safety (rua_cmd is currently not thread-safe, but it needs a lock, which I don't feel like doing at this stage).
This commit is contained in:
parent
f256ab167d
commit
340127fff2
7 changed files with 116 additions and 38 deletions
|
@ -58,6 +58,7 @@ typedef struct {
|
|||
} cmd_resources_t;
|
||||
|
||||
static hashtab_t *bi_cmds;
|
||||
static hashctx_t *bi_cmd_hashctx;
|
||||
static int bi_cmds_refs;
|
||||
|
||||
static const char *
|
||||
|
@ -129,6 +130,7 @@ bi_cmd_destroy (progs_t *pr, void *data)
|
|||
{
|
||||
if (!--bi_cmds_refs) {
|
||||
Hash_DelTable (bi_cmds);
|
||||
Hash_DelContext (bi_cmd_hashctx);
|
||||
}
|
||||
free (data);
|
||||
}
|
||||
|
@ -173,8 +175,9 @@ RUA_Cmd_Init (progs_t *pr, int secure)
|
|||
res->cmds = 0;
|
||||
|
||||
if (!bi_cmds) {
|
||||
//FIXME not thread-safe
|
||||
bi_cmds = Hash_NewTable (1021, bi_cmd_get_key, bi_cmd_free, 0,
|
||||
pr->hashctx);
|
||||
&bi_cmd_hashctx);
|
||||
}
|
||||
bi_cmds_refs++;
|
||||
|
||||
|
|
|
@ -140,13 +140,13 @@ font_new (gui_resources_t *res)
|
|||
{
|
||||
return PR_RESNEW (res->font_map);
|
||||
}
|
||||
/*
|
||||
|
||||
static void
|
||||
font_free (gui_resources_t *res, rua_font_t *font)
|
||||
{
|
||||
PR_RESFREE (res->font_map, font);
|
||||
}
|
||||
*/
|
||||
|
||||
static void
|
||||
font_reset (gui_resources_t *res)
|
||||
{
|
||||
|
@ -168,16 +168,16 @@ font_index (gui_resources_t *res, rua_font_t *font)
|
|||
static int
|
||||
alloc_font (gui_resources_t *res, font_t *font)
|
||||
{
|
||||
rua_font_t *psg = font_new (res);
|
||||
rua_font_t *fnt = font_new (res);
|
||||
|
||||
psg->next = res->fonts;
|
||||
psg->prev = &res->fonts;
|
||||
fnt->next = res->fonts;
|
||||
fnt->prev = &res->fonts;
|
||||
if (res->fonts) {
|
||||
res->fonts->prev = &psg->next;
|
||||
res->fonts->prev = &fnt->next;
|
||||
}
|
||||
res->fonts = psg;
|
||||
psg->font = font;
|
||||
return font_index (res, psg);
|
||||
res->fonts = fnt;
|
||||
fnt->font = font;
|
||||
return font_index (res, fnt);
|
||||
}
|
||||
|
||||
static rua_font_t * __attribute__((pure))
|
||||
|
@ -215,6 +215,8 @@ bi_gui_destroy (progs_t *pr, void *_res)
|
|||
{
|
||||
gui_resources_t *res = _res;
|
||||
ECS_DelRegistry (res->reg);
|
||||
PR_RESDELMAP (res->passage_map);
|
||||
PR_RESDELMAP (res->font_map);
|
||||
free (res);
|
||||
}
|
||||
|
||||
|
@ -231,6 +233,15 @@ bi (Font_Load)
|
|||
R_INT (pr) = alloc_font (res, font);
|
||||
}
|
||||
|
||||
bi (Font_Free)
|
||||
{
|
||||
gui_resources_t *res = _res;
|
||||
rua_font_t *font = get_font (res, P_INT (pr, 0));
|
||||
|
||||
Font_Free (font->font);
|
||||
font_free (res, font);
|
||||
}
|
||||
|
||||
bi (Passage_New)
|
||||
{
|
||||
gui_resources_t *res = _res;
|
||||
|
@ -361,6 +372,15 @@ bi (Text_Draw)
|
|||
}
|
||||
}
|
||||
|
||||
bi (View_Delete)
|
||||
{
|
||||
gui_resources_t *res = _res;
|
||||
uint32_t viewid = P_UINT (pr, 0);
|
||||
view_t view = { .id = viewid, .reg = res->reg,
|
||||
.comp = res->view_base + view_href };
|
||||
View_Delete (view);
|
||||
}
|
||||
|
||||
bi (View_ChildCount)
|
||||
{
|
||||
gui_resources_t *res = _res;
|
||||
|
@ -427,6 +447,7 @@ bi (View_UpdateHierarchy)
|
|||
#define P(a, s) { .size = (s), .alignment = BITOP_LOG2 (a), }
|
||||
static builtin_t builtins[] = {
|
||||
bi(Font_Load, 2, p(string), p(int)),
|
||||
bi(Font_Free, 2, p(int)),
|
||||
bi(Passage_New, 0),
|
||||
bi(Passage_ParseText, 2, p(ptr), p(string)),
|
||||
bi(Passage_Delete, 1, p(ptr)),
|
||||
|
@ -436,6 +457,7 @@ static builtin_t builtins[] = {
|
|||
bi(Text_View, 2, p(ptr), p(int)),
|
||||
bi(Text_SetScript, 4, p(uint), p(string), p(int), p (int)),
|
||||
|
||||
bi(View_Delete, 1, p(uint)),
|
||||
bi(View_ChildCount, 1, p(uint)),
|
||||
bi(View_GetChild, 2, p(uint), p(uint)),
|
||||
bi(View_SetPos, 3, p(uint), p(int), p(int)),
|
||||
|
|
|
@ -519,8 +519,7 @@ RUA_Input_Init (progs_t *pr, int secure)
|
|||
input_resources_t *res = calloc (sizeof (input_resources_t), 1);
|
||||
|
||||
res->cookie_super = new_memsuper ();
|
||||
res->cookies = Hash_NewTable (251, 0, rua_in_free_cookie, res,
|
||||
&res->hashctx);
|
||||
res->cookies = Hash_NewTable (251, 0, rua_in_free_cookie, res, pr->hashctx);
|
||||
Hash_SetHashCompare (res->cookies, rua_in_hash_cookie, rua_in_cmp_cookies);
|
||||
|
||||
PR_Resources_Register (pr, "input", res, bi_input_clear, bi_input_destroy);
|
||||
|
|
|
@ -106,7 +106,9 @@ bi_rua_model_clear (progs_t *pr, void *_res)
|
|||
static void
|
||||
bi_rua_model_destroy (progs_t *pr, void *_res)
|
||||
{
|
||||
free (_res);
|
||||
rua_model_resources_t *res = _res;
|
||||
PR_RESDELMAP (res->model_map);
|
||||
free (res);
|
||||
}
|
||||
|
||||
static int
|
||||
|
|
|
@ -45,6 +45,7 @@
|
|||
#include "qfalloca.h"
|
||||
|
||||
#include "QF/cvar.h"
|
||||
#include "QF/darray.h"
|
||||
#include "QF/dstring.h"
|
||||
#include "QF/hash.h"
|
||||
#include "QF/mathlib.h"
|
||||
|
@ -99,6 +100,8 @@ typedef struct obj_list_s {
|
|||
void *data;
|
||||
} obj_list;
|
||||
|
||||
typedef struct listset_s DARRAY_TYPE (obj_list *) listset_t;
|
||||
|
||||
typedef struct dtable_s {
|
||||
struct dtable_s *next;
|
||||
struct dtable_s **prev;
|
||||
|
@ -106,6 +109,13 @@ typedef struct dtable_s {
|
|||
pr_func_t *imp;
|
||||
} dtable_t;
|
||||
|
||||
typedef struct class_tree {
|
||||
pr_class_t *class;
|
||||
obj_list *subclasses;
|
||||
} class_tree;
|
||||
|
||||
typedef struct treeset_s DARRAY_TYPE (class_tree *) treeset_t;
|
||||
|
||||
typedef struct probj_resources_s {
|
||||
progs_t *pr;
|
||||
unsigned selector_index;
|
||||
|
@ -124,6 +134,7 @@ typedef struct probj_resources_s {
|
|||
hashtab_t *classes;
|
||||
hashtab_t *protocols;
|
||||
hashtab_t *load_methods;
|
||||
listset_t obj_list_sets;
|
||||
obj_list *obj_list_free_list;
|
||||
obj_list *unresolved_classes;
|
||||
obj_list *unclaimed_categories;
|
||||
|
@ -131,6 +142,9 @@ typedef struct probj_resources_s {
|
|||
obj_list *unclaimed_proto_list;
|
||||
obj_list *module_list;
|
||||
obj_list *class_tree_list;
|
||||
|
||||
class_tree *class_tree_free_list;
|
||||
treeset_t class_tree_sets;
|
||||
} probj_t;
|
||||
|
||||
static dtable_t *
|
||||
|
@ -184,8 +198,11 @@ obj_list_new (probj_t *probj)
|
|||
|
||||
if (!probj->obj_list_free_list) {
|
||||
probj->obj_list_free_list = calloc (128, sizeof (obj_list));
|
||||
for (i = 0; i < 127; i++)
|
||||
probj->obj_list_free_list[i].next = &probj->obj_list_free_list[i + 1];
|
||||
for (i = 0; i < 127; i++) {
|
||||
__auto_type next = &probj->obj_list_free_list[i + 1];
|
||||
probj->obj_list_free_list[i].next = next;
|
||||
}
|
||||
DARRAY_APPEND (&probj->obj_list_sets, probj->obj_list_free_list);
|
||||
}
|
||||
l = probj->obj_list_free_list;
|
||||
probj->obj_list_free_list = l->next;
|
||||
|
@ -230,28 +247,22 @@ list_remove (probj_t *probj, obj_list **list)
|
|||
}
|
||||
}
|
||||
|
||||
typedef struct class_tree {
|
||||
pr_class_t *class;
|
||||
obj_list *subclasses;
|
||||
} class_tree;
|
||||
|
||||
class_tree *class_tree_free_list;
|
||||
|
||||
static class_tree *
|
||||
class_tree_new (void)
|
||||
class_tree_new (probj_t *probj)
|
||||
{
|
||||
int i;
|
||||
class_tree *t;
|
||||
|
||||
if (!class_tree_free_list) {
|
||||
class_tree_free_list = calloc (128, sizeof (class_tree));
|
||||
if (!probj->class_tree_free_list) {
|
||||
probj->class_tree_free_list = calloc (128, sizeof (class_tree));
|
||||
for (i = 0; i < 127; i++) {
|
||||
class_tree *x = &class_tree_free_list[i];
|
||||
class_tree *x = &probj->class_tree_free_list[i];
|
||||
x->subclasses = (obj_list *) (x + 1);
|
||||
}
|
||||
DARRAY_APPEND (&probj->class_tree_sets, probj->class_tree_free_list);
|
||||
}
|
||||
t = class_tree_free_list;
|
||||
class_tree_free_list = (class_tree *) t->subclasses;
|
||||
t = probj->class_tree_free_list;
|
||||
probj->class_tree_free_list = (class_tree *) t->subclasses;
|
||||
t->subclasses = 0;
|
||||
return t;
|
||||
}
|
||||
|
@ -282,10 +293,10 @@ create_tree_of_subclasses_inherited_from (probj_t *probj, pr_class_t *bottom,
|
|||
|
||||
superclass = bottom->super_class ? Hash_Find (probj->classes, super_class)
|
||||
: 0;
|
||||
tree = prev = class_tree_new ();
|
||||
tree = prev = class_tree_new (probj);
|
||||
prev->class = bottom;
|
||||
while (superclass != upper) {
|
||||
tree = class_tree_new ();
|
||||
tree = class_tree_new (probj);
|
||||
tree->class = superclass;
|
||||
tree->subclasses = list_cons (probj, prev, tree->subclasses);
|
||||
super_class = PR_GetString (pr, superclass->super_class);
|
||||
|
@ -320,7 +331,7 @@ _obj_tree_insert_class (probj_t *probj, class_tree *tree, pr_class_t *class)
|
|||
return tree;
|
||||
list = list->next;
|
||||
}
|
||||
node = class_tree_new ();
|
||||
node = class_tree_new (probj);
|
||||
node->class = class;
|
||||
tree->subclasses = list_cons (probj, node, tree->subclasses);
|
||||
return tree;
|
||||
|
@ -381,8 +392,8 @@ obj_create_classes_tree (probj_t *probj, pr_module_t *module)
|
|||
static void
|
||||
obj_destroy_class_tree_node (probj_t *probj, class_tree *tree, int level)
|
||||
{
|
||||
tree->subclasses = (obj_list *) class_tree_free_list;
|
||||
class_tree_free_list = tree;
|
||||
tree->subclasses = (obj_list *) probj->class_tree_free_list;
|
||||
probj->class_tree_free_list = tree;
|
||||
}
|
||||
|
||||
static void
|
||||
|
@ -1414,6 +1425,18 @@ rua_obj_error (progs_t *pr, void *data)
|
|||
int count = pr->pr_argc - 3;
|
||||
pr_type_t **args = &pr->pr_params[3];
|
||||
|
||||
if (pr->progs->version == PROG_VERSION) {
|
||||
__auto_type va_list = &P_PACKED (pr, pr_va_list_t, 3);
|
||||
count = va_list->count;
|
||||
if (count) {
|
||||
args = alloca (count * sizeof (pr_type_t *));
|
||||
for (int i = 0; i < count; i++) {
|
||||
args[i] = &pr->pr_globals[va_list->list + i * 4];
|
||||
}
|
||||
} else {
|
||||
args = 0;
|
||||
}
|
||||
}
|
||||
obj_verror (probj, object, code, fmt, count, args);
|
||||
}
|
||||
|
||||
|
@ -2068,6 +2091,18 @@ rua__i_Object_error_error_ (progs_t *pr, void *data)
|
|||
int count = pr->pr_argc - 3;
|
||||
pr_type_t **args = &pr->pr_params[3];
|
||||
|
||||
if (pr->progs->version == PROG_VERSION) {
|
||||
__auto_type va_list = &P_PACKED (pr, pr_va_list_t, 3);
|
||||
count = va_list->count;
|
||||
if (count) {
|
||||
args = alloca (count * sizeof (pr_type_t *));
|
||||
for (int i = 0; i < count; i++) {
|
||||
args[i] = &pr->pr_globals[va_list->list + i * 4];
|
||||
}
|
||||
} else {
|
||||
args = 0;
|
||||
}
|
||||
}
|
||||
dsprintf (probj->msg, "error: %s (%s)\n%s",
|
||||
PR_GetString (pr, object_get_class_name (probj, self)),
|
||||
object_is_instance (probj, self) ? "instance" : "class", fmt);
|
||||
|
@ -2336,10 +2371,16 @@ rua_obj_destroy (progs_t *pr, void *_res)
|
|||
free (probj->selector_sels);
|
||||
free (probj->selector_names);
|
||||
free (probj->selector_argc);
|
||||
//FIXME free (probj->obj_list_free_list);
|
||||
|
||||
//FIXME free (class_tree_free_list);
|
||||
//FIXME class_tree_free_list = 0;
|
||||
for (size_t i = 0; i < probj->obj_list_sets.size; i++) {
|
||||
free (probj->obj_list_sets.a[i]);
|
||||
}
|
||||
DARRAY_CLEAR (&probj->obj_list_sets);
|
||||
|
||||
for (size_t i = 0; i < probj->class_tree_sets.size; i++) {
|
||||
free (probj->class_tree_sets.a[i]);
|
||||
}
|
||||
DARRAY_CLEAR (&probj->class_tree_sets);
|
||||
|
||||
PR_RESDELMAP (probj->dtables);
|
||||
|
||||
|
@ -2358,9 +2399,11 @@ RUA_Obj_Init (progs_t *pr, int secure)
|
|||
probj->protocols = Hash_NewTable (1021, protocol_get_key, 0, probj,
|
||||
pr->hashctx);
|
||||
probj->load_methods = Hash_NewTable (1021, 0, 0, probj, pr->hashctx);
|
||||
probj->msg = dstring_newstr();
|
||||
Hash_SetHashCompare (probj->load_methods, load_methods_get_hash,
|
||||
load_methods_compare);
|
||||
probj->msg = dstring_newstr();
|
||||
DARRAY_INIT (&probj->obj_list_sets, 32);
|
||||
DARRAY_INIT (&probj->class_tree_sets, 32);
|
||||
|
||||
PR_Sprintf_SetAtHandler (pr, rua_at_handler, probj);
|
||||
|
||||
|
|
|
@ -657,7 +657,10 @@ bi_scene_clear (progs_t *pr, void *_res)
|
|||
static void
|
||||
bi_scene_destroy (progs_t *pr, void *_res)
|
||||
{
|
||||
free (_res);
|
||||
rua_scene_resources_t *res = _res;
|
||||
PR_RESDELMAP (res->scene_map);
|
||||
PR_RESDELMAP (res->lighting_map);
|
||||
free (res);
|
||||
}
|
||||
|
||||
void
|
||||
|
|
|
@ -480,6 +480,12 @@ main (int argc, char **argv)
|
|||
ret = thread_data.a[main_ind]->return_code;
|
||||
}
|
||||
|
||||
for (size_t i = 0; i < thread_data.size; i++) {
|
||||
qwaq_thread_t *thread = thread_data.a[i];
|
||||
DARRAY_CLEAR (&thread->args);
|
||||
free (thread_data.a[i]);
|
||||
}
|
||||
DARRAY_CLEAR (&thread_data);
|
||||
Cbuf_Delete (qwaq_cbuf);
|
||||
Sys_Shutdown ();
|
||||
return ret;
|
||||
|
|
Loading…
Reference in a new issue