Clean up all refs when a stage ends, print a warning if some leaked
This commit is contained in:
parent
3b422b803e
commit
4acfc71887
4 changed files with 45 additions and 7 deletions
49
src/list.c
49
src/list.c
|
@ -62,27 +62,40 @@ void delete_all_elements(void **dest, void (callback)(void **, void *)) {
|
|||
*dest = NULL;
|
||||
}
|
||||
|
||||
#ifdef DEBUG
|
||||
// #define DEBUG_REFS
|
||||
#endif
|
||||
|
||||
#ifdef DEBUG_REFS
|
||||
#define REFLOG(...) fprintf(stderr, __VA_ARGS__);
|
||||
#else
|
||||
#define REFLOG(...)
|
||||
#endif
|
||||
|
||||
int add_ref(void *ptr) {
|
||||
int i;
|
||||
int i, firstfree = -1;
|
||||
|
||||
for(i = 0; i < global.refs.count; i++) {
|
||||
if(global.refs.ptrs[i].ptr == ptr) {
|
||||
global.refs.ptrs[i].refs++;
|
||||
REFLOG("increased refcount for %p (ref %i): %i\n", ptr, i, global.refs.ptrs[i].refs);
|
||||
return i;
|
||||
} else if(firstfree < 0 && global.refs.ptrs[i].ptr == FREEREF) {
|
||||
firstfree = i;
|
||||
}
|
||||
}
|
||||
|
||||
for(i = 0; i < global.refs.count; i++) {
|
||||
if(global.refs.ptrs[i].ptr == FREEREF) {
|
||||
global.refs.ptrs[i].ptr = ptr;
|
||||
global.refs.ptrs[i].refs = 1;
|
||||
return i;
|
||||
}
|
||||
if(firstfree >= 0) {
|
||||
global.refs.ptrs[firstfree].ptr = ptr;
|
||||
global.refs.ptrs[firstfree].refs = 1;
|
||||
REFLOG("found free ref for %p: %i\n", ptr, firstfree);
|
||||
return firstfree;
|
||||
}
|
||||
|
||||
global.refs.ptrs = realloc(global.refs.ptrs, (++global.refs.count)*sizeof(Reference));
|
||||
global.refs.ptrs[global.refs.count - 1].ptr = ptr;
|
||||
global.refs.ptrs[global.refs.count - 1].refs = 1;
|
||||
REFLOG("new ref for %p: %i\n", ptr, global.refs.count - 1);
|
||||
|
||||
return global.refs.count - 1;
|
||||
}
|
||||
|
@ -100,8 +113,30 @@ void free_ref(int i) {
|
|||
return;
|
||||
|
||||
global.refs.ptrs[i].refs--;
|
||||
REFLOG("decreased refcount for %p (ref %i): %i\n", global.refs.ptrs[i].ptr, i, global.refs.ptrs[i].refs);
|
||||
|
||||
if(global.refs.ptrs[i].refs <= 0) {
|
||||
global.refs.ptrs[i].ptr = FREEREF;
|
||||
global.refs.ptrs[i].refs = 0;
|
||||
REFLOG("ref %i is now free\n", i);
|
||||
}
|
||||
}
|
||||
|
||||
void free_all_refs(void) {
|
||||
int inuse = 0;
|
||||
int inuse_unique = 0;
|
||||
|
||||
for(int i = 0; i < global.refs.count; i++) {
|
||||
if(global.refs.ptrs[i].refs) {
|
||||
inuse += global.refs.ptrs[i].refs;
|
||||
inuse_unique += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(inuse) {
|
||||
warnx("free_all_refs(): %i refs were still in use (%i unique, %i total allocated)", inuse, inuse_unique, global.refs.count);
|
||||
}
|
||||
|
||||
free(global.refs.ptrs);
|
||||
memset(&global.refs, 0, sizeof(RefArray));
|
||||
}
|
||||
|
|
|
@ -32,4 +32,5 @@ extern void *_FREEREF;
|
|||
int add_ref(void *ptr);
|
||||
void del_ref(void *ptr);
|
||||
void free_ref(int i);
|
||||
void free_all_refs(void);
|
||||
#endif
|
||||
|
|
|
@ -25,6 +25,7 @@ void taisei_shutdown(void) {
|
|||
if(!config_get_int(CONFIG_NO_AUDIO)) shutdown_sfx();
|
||||
if(!config_get_int(CONFIG_NO_MUSIC)) shutdown_bgm();
|
||||
|
||||
free_all_refs();
|
||||
free_resources();
|
||||
video_shutdown();
|
||||
gamepad_shutdown();
|
||||
|
|
|
@ -785,6 +785,7 @@ void stage_loop(StageInfo *stage) {
|
|||
stage->procs->end();
|
||||
stage_free();
|
||||
tsrand_switch(&global.rand_visual);
|
||||
free_all_refs();
|
||||
}
|
||||
|
||||
static void draw_title(int t, StageInfo *info, Alignment al, int x, int y, const char *text, TTF_Font *font, Color *color) {
|
||||
|
|
Loading…
Reference in a new issue