windows-nt/Source/XPSP1/NT/inetsrv/iis/staxinc/transmem.h
2020-09-26 16:20:57 +08:00

238 lines
6.1 KiB
C

//-----------------------------------------------------------------------------
//
// File: TRANSMEM.H
//
// Copyright Microsoft Corporation 1997, All Rights Reserved.
//
// Owner: NIKOS
//
// Description: This file contains memory routines and macros for using
// EXCHMEM as a dynamic memory allocator. If your object can
// be made fixed in size, it may be more appropriate to use
// CPool especially if your object is allocated/freed often.
//
// Note: CPool never releases (frees) objects, so some sort of
// free such objects may also be needed.
//
// Modified 2/98 by mikeswa - Added Multi-heap support
//-----------------------------------------------------------------------------
#ifndef __TRANSMEM_H__
#define __TRANSMEM_H__
#include <exchmem.h>
#include <cpool.h>
#define HEAP_LOW_MEMORY_RESERVE 65536 // to be freed when we're low on memory
//define number of exchmem heaps if not already defined
#ifndef NUM_EXCHMEM_HEAPS
#define NUM_EXCHMEM_HEAPS 0
#endif //NUM_EXCHMEM_HEAPS
//
// These three globals:
//
// HANDLE g_hTransHeap = NULL;
//
// must be declared somewhere in a C file so things will link properly. The macros
// declared use these to store heap handles, etc. to make things work.
//
#ifdef __cplusplus
extern "C" {
#endif
extern HANDLE g_hTransHeap;
#ifdef __cplusplus
}
#endif
//
// TrHeapCreate needs to be called once at startup time to initialize Exchmem and create
// the heap.
//
#ifdef __cplusplus
__inline BOOL TrHeapCreate(DWORD dwFlags=0, DWORD dwInitialSize=1024000, DWORD dwMaxSize=0)
#else
__inline BOOL TrHeapCreate(DWORD dwFlags, DWORD dwInitialSize, DWORD dwMaxSize)
#endif
{
if (g_hTransHeap)
return FALSE;
g_hTransHeap = ExchMHeapCreate(NUM_EXCHMEM_HEAPS, dwFlags, dwInitialSize, dwMaxSize);
if (g_hTransHeap)
return TRUE;
else
return FALSE;
}
//
// TrHeapDestroy() needs to be called once at shutdown time to free the heap and it's contents.
//
// Note: Because the heap is destroyed before the module is finished unloading, all objects that
// allocated memory must be destroyed (with delete) before the module is unloaded. If not
// done, nasty crashes will result. This is a BAD thing to do:
//
// CObject g_Object;
//
// CObject::~CObject()
// {
// if (NULL != m_pBuffer)
// {
// TrFree(m_pBuffer);
// m_pBuffer = NULL;
// }
// }
//
// since ~CObject() will be called AFTER TrHeapDestroy, and TrFree will be called on a (destroyed) heap.
//
__inline BOOL TrHeapDestroy(void)
{
BOOL b = TRUE;
if (g_hTransHeap)
{
b = ExchMHeapDestroy();
g_hTransHeap = NULL;
}
return b;
}
//
// TrCalloc: replacement for calloc()
//
__inline void * TrCalloc(unsigned int x, unsigned int y, char * szFile = __FILE__, unsigned int uiLine = __LINE__)
{
return g_hTransHeap ? ExchMHeapAllocDebug(x*y, szFile, uiLine) : NULL;
}
//
// TrFree: replacement for free()
__inline void TrFree(void *pv)
{
if (g_hTransHeap)
{
ExchMHeapFree(pv);
}
else
{
// Our allocs / frees are out of sync.
#ifdef DEBUG
DebugBreak();
#endif
}
}
// TrMalloc: replacement for malloc()
__inline void * TrMalloc(unsigned int size, char * szFile = __FILE__, unsigned int uiLine = __LINE__)
{
return g_hTransHeap ? ExchMHeapAllocDebug(size, szFile, uiLine) : NULL;
}
// TrRealloc: replacement for realloc()
__inline void * TrRealloc(void *pv, unsigned int size, char * szFile = __FILE__, unsigned int uiLine = __LINE__)
{
return g_hTransHeap ? ExchMHeapReAllocDebug(pv, size, szFile, uiLine) : NULL;
}
#ifdef __cplusplus
#define TransCONST const
#else
#define TransCONST
#endif
// TrStrdupW: replacement for wcsdup()
__inline LPWSTR TrStrdupW(TransCONST LPWSTR pwszString)
{
LPWSTR pwszTmp = NULL;
if (NULL == g_hTransHeap || NULL == pwszString)
return NULL;
pwszTmp = (LPWSTR) ExchMHeapAlloc((wcslen(pwszString) + 1) * sizeof(WCHAR));
if (NULL != pwszTmp)
wcscpy(pwszTmp,pwszString);
return pwszTmp;
}
// TrStrdupA: replacement for strdup()
__inline LPSTR TrStrdupA(TransCONST LPSTR pszString)
{
LPSTR pszTmp = NULL;
if (NULL == g_hTransHeap || NULL == pszString)
return NULL;
pszTmp = (LPSTR) ExchMHeapAlloc((strlen(pszString) + 1) * sizeof(CHAR));
if (NULL != pszTmp)
strcpy(pszTmp,pszString);
return pszTmp;
}
#ifdef _UNICODE
#define TrStrdup(x) TrStrdupW(x)
#else
#define TrStrdup(x) TrStrdupA(x)
#endif
//
// Please use the pv* macros... defined here allocators may change over time and this will
// make it easy to change when needed.
//
#define pvMalloc(x) TrMalloc(x, __FILE__, __LINE__)
#define FreePv(x) TrFree(x)
#define pvCalloc(x,y) TrCalloc(x,y, __FILE__, __LINE__)
#define pszStrdup(x) TrStrdup(x)
#define pvRealloc(pv,size) TrRealloc(pv, size, __FILE__, __LINE__)
#ifdef __cplusplus
// Replacement for the default new() operator
__inline void * __cdecl operator new(size_t stAllocateBlock)
{
return TrMalloc( stAllocateBlock );
}
// Replacement for the default new() operator that allows
//specification of file and line #
// To use this allocator as your default allocator, simply use the following:
//#define new TRANSMEM_NEW
//NOTE: You must be careful when you redefine this macro... it may cause
//problems with overloaded new operators (a la CPOOL or STL).
#define TRANSMEM_NEW new(__FILE__, __LINE)
__inline void * __cdecl operator new(size_t stAllocateBlock, char * szFile, unsigned int uiLine)
{
return TrMalloc( stAllocateBlock, szFile, uiLine );
}
// Replacement for the default delete() operator
__inline void __cdecl operator delete( void *pvMem )
{
FreePv( pvMem );
}
#endif
// Convenient macro to set the pointer you freed to NULL as well
#define TRFREE(x) \
if (NULL != x) \
{ \
FreePv(x); \
x = NULL; \
}
// Convenient macro to set the pointer to the object to NULL as well
#define TRDELETE(x) \
if (NULL != x) \
{ \
delete x; \
x = NULL; \
}
#endif /* __TRANSMEM_H__ */