malloc.cpp

来自「firtext搜索引擎源码」· C++ 代码 · 共 618 行 · 第 1/2 页

CPP
618
字号

	if (malloc32.pSpy) {
		::pthread_mutex_lock( &mutex );
	    pv = malloc32.pSpy->PreDidAlloc(pv, fSpyed);
	}

	int16_t didAlloc = -1;

	if( malloc32.pSpy ) {
	    didAlloc = malloc32.pSpy->PostDidAlloc(pv, fSpyed, didAlloc);
		::pthread_mutex_unlock( &mutex );
	}
	return didAlloc;
}

/******************************************************************************
 * IMalloc32_HeapMinimize [VTABLE]
 */
void firtex::com::internal::Malloc::HeapMinimize() 
{

	if(malloc32.pSpy ) {
		::pthread_mutex_lock( &mutex );
	    malloc32.pSpy->PreHeapMinimize();
	}

	if(malloc32.pSpy) {
	    malloc32.pSpy->PostHeapMinimize();
		::pthread_mutex_unlock( &mutex );
	}
}

/******************************************************************************
 *	IMallocSpy implementation
 *****************************************************************************/
namespace firtex
{
	namespace com 
	{
		namespace internal 
		{
			class MallocSpy : public IMallocSpy 
			{
			public:
				MallocSpy();
				~MallocSpy();

				FX_STDMETHOD(QueryInterface)(FX_REFIID riid, void** ptr );
				FX_STDMETHOD_(uint32_t,AddRef)();
				FX_STDMETHOD_(uint32_t,Release)();
				FX_STDMETHOD_(uint32_t,PreAlloc)(uint32_t cbRequest);
				FX_STDMETHOD_(void*,PostAlloc)(void __RPC_FAR *pActual);
				FX_STDMETHOD_(void*,PreFree)(void __RPC_FAR *pRequest,bool_t fSpyed);
				FX_STDMETHOD_(void,PostFree)(bool_t fSpyed);
				FX_STDMETHOD_(uint32_t,PreRealloc)(void __RPC_FAR *pRequest,
					uint32_t cbRequest,void __RPC_FAR *__RPC_FAR *ppNewRequest,bool_t fSpyed);
				FX_STDMETHOD_(void*,PostRealloc)(void __RPC_FAR *pActual,bool_t fSpyed);
				FX_STDMETHOD_(void*,PreGetSize)(void __RPC_FAR *pRequest,bool_t fSpyed);
				FX_STDMETHOD_(uint32_t,PostGetSize)(uint32_t cbActual,bool_t fSpyed);
				FX_STDMETHOD_(void*,PreDidAlloc)(void __RPC_FAR *pRequest,bool_t fSpyed);
				FX_STDMETHOD_(int16_t,PostDidAlloc)(void __RPC_FAR *pRequest,bool_t fSpyed,int16_t fActual);
				FX_STDMETHOD_(void,PreHeapMinimize)( void);
				FX_STDMETHOD_(void,PostHeapMinimize)( void);

			private:
				uint32_t ref;	
			};
		}
	}
}



static firtex::com::internal::MallocSpy mallocspy32;

firtex::com::internal::MallocSpy::MallocSpy()
{
	ref = 0;
}

firtex::com::internal::MallocSpy::~MallocSpy()
{
	if ( ref != 0 )
		internal::log_printf( internal::WARN, "(%ld) - Reference count for internal MallocSpy not zero.\n", ref );
}


/******************************************************************************
 *	IMalloc32_QueryInterface	[VTABLE]
 */
firtex::com::FX_HRESULT firtex::com::internal::MallocSpy::QueryInterface(FX_REFIID refiid,void** obj)
{
	if ( FX_IsEqualIID(IUnknown::iid,refiid) ) {
		*obj = static_cast<IUnknown*>(this);
		AddRef();
		return FX_S_OK;
	}
	if ( FX_IsEqualIID(IMallocSpy::iid,refiid) ) {
		*obj = static_cast<IMallocSpy*>(this);
		AddRef();
		return FX_S_OK;
	}
	return FX_E_NOINTERFACE;
}

/******************************************************************************
 *	IMalloc32_AddRef		[VTABLE]
 */
uint32_t firtex::com::internal::MallocSpy::AddRef()
{
	pthread_mutex_lock lock(&mutex);
	return ++ref;
}

/******************************************************************************
 *	IMalloc32_AddRelease		[VTABLE]
 *
 * NOTES
 *   Our MallocSpy is static. If the count reaches 0 we dump the leaks
 */
uint32_t firtex::com::internal::MallocSpy::Release()
{
	pthread_mutex_lock lock(&mutex);
	return --ref;
}

uint32_t firtex::com::internal::MallocSpy::PreAlloc(uint32_t cbRequest)
{
    return cbRequest;
}

void* firtex::com::internal::MallocSpy::PostAlloc(void* pActual)
{
    return pActual;
}

void* firtex::com::internal::MallocSpy::PreFree(void* pRequest, firtex::com::bool_t fSpyed)
{
    return pRequest;
}
void firtex::com::internal::MallocSpy::PostFree(firtex::com::bool_t fSpyed)
{
	// do nothing
}

uint32_t firtex::com::internal::MallocSpy::PreRealloc(void* pRequest, uint32_t cbRequest, void** ppNewRequest, firtex::com::bool_t fSpyed)
{
    *ppNewRequest = pRequest;
    return cbRequest;
}

void* firtex::com::internal::MallocSpy::PostRealloc(void* pActual, firtex::com::bool_t fSpyed)
{
    return pActual;
}

void* firtex::com::internal::MallocSpy::PreGetSize(void* pRequest, firtex::com::bool_t fSpyed)
{
    return pRequest;
}

uint32_t firtex::com::internal::MallocSpy::PostGetSize(uint32_t cbActual, firtex::com::bool_t fSpyed)
{
    return cbActual;
}

void* firtex::com::internal::MallocSpy::PreDidAlloc(void* pRequest, firtex::com::bool_t fSpyed)
{
    return pRequest;
}

int16_t firtex::com::internal::MallocSpy::PostDidAlloc(void* pRequest, firtex::com::bool_t fSpyed, int16_t fActual)
{
    return fActual;
}

void firtex::com::internal::MallocSpy::PreHeapMinimize()
{
	// do nothing
}

void firtex::com::internal::MallocSpy::PostHeapMinimize()
{
	// do nothing
}

static void MallocSpyDumpLeaks() {
	firtex::com::internal::log_printf( firtex::com::internal::ERROR, "leaks: %lu\n", malloc32.SpyedAllocationsLeft);
}

/******************************************************************************
 *		FX_CoGetMalloc	[OLE32.@]
 *
 * RETURNS
 *	The win32 IMalloc
 */
firtex::com::FX_HRESULT firtex::com::FX_CoGetMalloc(uint32_t dwMemContext, firtex::com::IMalloc** lpMalloc)
{
	if ( !lpMalloc ) return FX_E_INVALIDARG;
        *lpMalloc = &malloc32;
        //? malloc32->AddRef();
        return FX_S_OK;
}

/***********************************************************************
 *           FX_CoTaskMemAlloc     [OLE32.@]
 * RETURNS
 * 	pointer to newly allocated block
 */
void* firtex::com::FX_CoTaskMemAlloc(uint32_t size)
{
	return malloc32.Alloc( size );
}
/***********************************************************************
 *           FX_CoTaskMemFree      [OLE32.@]
 */
void firtex::com::FX_CoTaskMemFree(void* ptr)
{
	malloc32.Free( ptr );
}

/***********************************************************************
 *           FX_CoTaskMemRealloc   [OLE32.@]
 * RETURNS
 * 	pointer to newly allocated block
 */
void* firtex::com::FX_CoTaskMemRealloc(void* pvOld, uint32_t size)
{
	return malloc32.Realloc( pvOld, size );
}

/***********************************************************************
 *           FX_CoRegisterMallocSpy        [OLE32.@]
 *
 * NOTES
 *  if a mallocspy is already registered, we can't do it again since
 *  only the spy knows, how to free a memory block
 */
firtex::com::FX_HRESULT firtex::com::FX_CoRegisterMallocSpy(firtex::com::IMallocSpy* pMallocSpy)
{

	/* HACK TO ACTIVATE OUT SPY */
	if ( pMallocSpy == reinterpret_cast<void*>(-1) ) {
		pMallocSpy = &mallocspy32;
	}

	if ( malloc32.pSpy) {
		return FX_CO_E_OBJISREG;
	}
	
	internal::pthread_mutex_lock lock(&mutex);

	IMallocSpy* pSpy = 0;
	FX_HRESULT hr = pMallocSpy->QueryInterface( IMallocSpy::iid, (void**)pSpy ); 
	if ( FX_FAILED(hr) ) return FX_E_INVALIDARG;
	assert( pSpy );
	
	malloc32.pSpy = pSpy;
	return FX_S_OK;
}

/***********************************************************************
 *           FX_CoRevokeMallocSpy  [OLE32.@]
 *
 * NOTES
 *  we can't revoke a malloc spy as long as memory blocks allocated with
 *  the spy are active since only the spy knows how to free them
 */
firtex::com::FX_HRESULT firtex::com::FX_CoRevokeMallocSpy(void)
{
 	internal::pthread_mutex_lock lock(&mutex);
 	
	/* if it's our spy it's time to dump the leaks */
	if ( malloc32.pSpy == &mallocspy32 ) {
	    MallocSpyDumpLeaks();
	}

	if ( malloc32.SpyedAllocationsLeft ) {
	    internal::log_printf( internal::INFO, "SpyReleasePending with %lu allocations left\n", malloc32.SpyedAllocationsLeft);
	    malloc32.SpyReleasePending = true;
	    return FX_E_ACCESSDENIED;

	}
	else if ( malloc32.pSpy ) {
		malloc32.pSpy->Release();
    		malloc32.pSpy = NULL;
        }

	return FX_S_OK;
}

/******************************************************************************
 *		IsValidInterface	[OLE32.@]
 *
 * RETURNS
 *  True, if the passed pointer is a valid interface
 */
/*BOOL WINAPI IsValidInterface(
	LPUNKNOWN punk	// [in] interface to be tested
) {
	return !(
		IsBadReadPtr(punk,4)					||
		IsBadReadPtr(punk->lpVtbl,4)				||
		IsBadReadPtr(punk->lpVtbl->QueryInterface,9)	||
		IsBadCodePtr((FARPROC)punk->lpVtbl->QueryInterface)
	);
}
*/

⌨️ 快捷键说明

复制代码Ctrl + C
搜索代码Ctrl + F
全屏模式F11
增大字号Ctrl + =
减小字号Ctrl + -
显示快捷键?