[host] win: add comRef helpers for leak identification and tracking

This commit is contained in:
Geoffrey McRae 2024-02-05 02:46:57 +11:00
parent 0b210a280d
commit 4076377820
2 changed files with 22 additions and 12 deletions

View File

@ -25,6 +25,7 @@
#include <windows.h> #include <windows.h>
#include <malloc.h> #include <malloc.h>
#include "common/util.h"
#include "common/locking.h" #include "common/locking.h"
/** /**
@ -42,10 +43,10 @@ struct ComScope
unsigned used; unsigned used;
struct struct
{ {
IUnknown *** ptr;
IUnknown * ref; IUnknown * ref;
const char * where;
} }
* refs; *refs;
void (*free)(void * ptr); void (*free)(void * ptr);
}; };
@ -55,7 +56,7 @@ void comRef_initScope(unsigned size, ComScope ** instance,
void comRef_freeScope(ComScope ** instance); void comRef_freeScope(ComScope ** instance);
IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst); IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst, const char * where);
#define comRef_initGlobalScope(size, scope) \ #define comRef_initGlobalScope(size, scope) \
comRef_initScope((size), &(scope), malloc, free, true) comRef_initScope((size), &(scope), malloc, free, true)
@ -73,11 +74,13 @@ IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst);
#define comRef_defineLocal(type, name) \ #define comRef_defineLocal(type, name) \
type ** name = NULL; \ type ** name = NULL; \
comRef_new(_comRef_localScope, (IUnknown ***)&(name)); comRef_new(_comRef_localScope, (IUnknown ***)&(name), \
STR(name));
#define _comRef_toGlobal(globalScope, dst, src) \ #define _comRef_toGlobal(globalScope, dst, src) \
{ \ { \
IUnknown ** global = comRef_new((globalScope), (IUnknown ***)&(dst)); \ IUnknown ** global = comRef_new((globalScope), (IUnknown ***)&(dst), \
STR(dst)); \
*global = (IUnknown *)*(src); \ *global = (IUnknown *)*(src); \
*(src) = NULL; \ *(src) = NULL; \
} }

View File

@ -55,12 +55,17 @@ void comRef_freeScope(ComScope ** instance)
typeof(scope->refs) ref = &scope->refs[i]; typeof(scope->refs) ref = &scope->refs[i];
if (ref->ref) if (ref->ref)
{ {
IUnknown_Release(ref->ref); ULONG count = IUnknown_Release(ref->ref);
#ifdef DEBUG_COMREF
if (count > 0 && scope->free)
DEBUG_INFO("comRef %s release is %lu", ref->where, count);
#else
(void)count;
#endif
ref->ref = NULL; ref->ref = NULL;
} }
*ref->ptr = NULL;
ref->ptr = NULL;
} }
if (scope->threadSafe) if (scope->threadSafe)
@ -72,7 +77,7 @@ void comRef_freeScope(ComScope ** instance)
*instance = NULL; *instance = NULL;
} }
IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst) IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst, const char * where)
{ {
/* check if the value it points to is already in our memory range and if it /* check if the value it points to is already in our memory range and if it
* does, then reuse it */ * does, then reuse it */
@ -97,8 +102,10 @@ IUnknown ** comRef_new(ComScope * scope, IUnknown *** dst)
if (scope->threadSafe) if (scope->threadSafe)
LG_LOCK(scope->lock); LG_LOCK(scope->lock);
scope->refs[scope->used].ptr = dst; typeof(scope->refs[0]) * ref = &scope->refs[scope->used];
*dst = &scope->refs[scope->used].ref; ref->where = where;
*dst = &ref->ref;
++scope->used; ++scope->used;
if (scope->threadSafe) if (scope->threadSafe)