mirror of
				https://github.com/gnif/LookingGlass.git
				synced 2025-11-04 06:31:54 +00:00 
			
		
		
		
	[host] win: add comRef helpers for leak identification and tracking
This commit is contained in:
		@@ -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; \
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user