/*=================================================================== Microsoft Denali Microsoft Confidential. Copyright 1996 Microsoft Corporation. All Rights Reserved. Component: Per-Class Memory Management File: Memcls.cpp Owner: dmitryr This file contains the code to access ATQ memory cache on per class basis ===================================================================*/ #include "denpre.h" #pragma hdrstop #include "asperror.h" #include "clcert.h" #include "context.h" #include "cookies.h" #include "request.h" #include "response.h" #include "server.h" #include "strlist.h" #include "tlbcache.h" #include "memcls.h" // Don't #include "memchk.h" in this file /*=================================================================== DEBUG only gs_cTotalObjectsLeaked counts memory leaks DebugCheckLeaks() outputs the ATQ cache memory leaks into denmem.log DEBUG_ACACHE_UNINIT() and DEBUG_ACACHE_FSA_UNINIT() call DebugCheckLeaks() in DEBUG mode only ===================================================================*/ #ifdef DBG static DWORD gs_cTotalObjectsLeaked = 0; #define SZ_MEMCLS_LOG_FILE "C:\\TEMP\\MEMCLS.LOG" static void DebugCheckLeaks(ALLOC_CACHE_HANDLER *pach, const char *szClass) { ALLOC_CACHE_STATISTICS acStats; pach->QueryStats(&acStats); DWORD cLeaked = acStats.nTotal - acStats.nFreeEntries; if (cLeaked > 0) { gs_cTotalObjectsLeaked += cLeaked; DebugFilePrintf ( SZ_MEMCLS_LOG_FILE, "MEMCLS: ATQ allocation cache leak: %d of %s objects.\n", cLeaked, szClass ); } } #define DEBUG_ACACHE_UNINIT(C) { DebugCheckLeaks(C::sm_pach, #C); \ ACACHE_UNINIT(C) } #define DEBUG_ACACHE_FSA_UNINIT(C) { DebugCheckLeaks(g_pach##C, #C); \ ACACHE_FSA_UNINIT(C) } #else #define DEBUG_ACACHE_UNINIT(C) ACACHE_UNINIT(C) #define DEBUG_ACACHE_FSA_UNINIT(C) ACACHE_FSA_UNINIT(C) #endif /*=================================================================== For each class with ACACHE_INCLASS_DEFINITIONS() inside add here ACACHE_CODE macro. ===================================================================*/ ACACHE_CODE(C449Cookie) ACACHE_CODE(C449File) ACACHE_CODE(CASEElem) ACACHE_CODE(CActiveScriptEngine) ACACHE_CODE(CAppln) ACACHE_CODE(CApplnVariants) ACACHE_CODE(CASPError) ACACHE_CODE(CClCert) ACACHE_CODE(CComponentCollection) ACACHE_CODE(CComponentObject) ACACHE_CODE(CCookie) ACACHE_CODE(CDebugResponseBuffer) ACACHE_CODE(CEngineDispElem) ACACHE_CODE(CFileApplnList) ACACHE_CODE(CHitObj) ACACHE_CODE(CHTTPHeader) ACACHE_CODE(CIsapiReqInfo) ACACHE_CODE(CPageComponentManager) ACACHE_CODE(CPageObject) ACACHE_CODE(CRequest) ACACHE_CODE(CRequestData) ACACHE_CODE(CRequestHit) ACACHE_CODE(CResponse) ACACHE_CODE(CResponseBuffer) ACACHE_CODE(CResponseData) ACACHE_CODE(CScriptingNamespace) ACACHE_CODE(CScriptingContext) ACACHE_CODE(CServer) ACACHE_CODE(CServerData) ACACHE_CODE(CSession) ACACHE_CODE(CSessionVariants) ACACHE_CODE(CStringList) ACACHE_CODE(CStringListElem) ACACHE_CODE(CTemplate) //ACACHE_CODE(CTemplate::CBuffer) ACACHE_CODE(CTemplate::CFileMap) ACACHE_CODE(CTypelibCacheEntry) ACACHE_CODE(CVariantsIterator) ACACHE_CODE(CViperActivity) ACACHE_CODE(CViperAsyncRequest) /*=================================================================== For each fixed size allocator add here ACACHE_FSA_DEFINITION macro. ===================================================================*/ ACACHE_FSA_DEFINITION(MemBlock128) ACACHE_FSA_DEFINITION(MemBlock256) ACACHE_FSA_DEFINITION(ResponseBuffer) /*=================================================================== Defines for cache threshold of each kind ===================================================================*/ #define HARDCODED_PER_APPLN_CACHE_MAX 128 #define HARDCODED_PER_REQUEST_CACHE_MAX 1024 #define HARDCODED_PER_QUEUEITEM_CACHE_MAX 8192 #define HARDCODED_PER_SESSION_CACHE_MAX 8192 #define HARDCODED_PER_SCRPTENG_CACHE_MAX 256 #define HARDCODED_PER_TEMPLATE_CACHE_MAX 2048 #define HARDCODED_PER_RESPONSE_BUFFER_MAX 64 #define HARDCODED_PER_SIZE_BUFFER_MAX 4096 // do scaling per registry setting DWORD dwMemClsScaleFactor; #define PER_APPLN_CACHE_MAX ((HARDCODED_PER_APPLN_CACHE_MAX * dwMemClsScaleFactor) / 100) #define PER_REQUEST_CACHE_MAX ((HARDCODED_PER_REQUEST_CACHE_MAX * dwMemClsScaleFactor) / 100) #define PER_QUEUEITEM_CACHE_MAX ((HARDCODED_PER_QUEUEITEM_CACHE_MAX * dwMemClsScaleFactor) / 100) #define PER_SESSION_CACHE_MAX ((HARDCODED_PER_SESSION_CACHE_MAX * dwMemClsScaleFactor) / 100) #define PER_SCRPTENG_CACHE_MAX ((HARDCODED_PER_SCRPTENG_CACHE_MAX * dwMemClsScaleFactor) / 100) #define PER_TEMPLATE_CACHE_MAX ((HARDCODED_PER_TEMPLATE_CACHE_MAX * dwMemClsScaleFactor) / 100) #define PER_RESPONSE_BUFFER_MAX ((HARDCODED_PER_RESPONSE_BUFFER_MAX * dwMemClsScaleFactor) / 100) #define PER_SIZE_BUFFER_MAX ((HARDCODED_PER_SIZE_BUFFER_MAX * dwMemClsScaleFactor) / 100) /*=================================================================== InitMemCls To be called from DllInit(). Creates per-class ATQ memory allocators. For each class with ACACHE_INCLASS_DEFINITIONS() inside add here ACACHE_INIT macro. For each ACACHE_FSA_DEFINITION() add here ACACHE_FSA_INIT macro. Parameters Returns: HRESULT ===================================================================*/ HRESULT InitMemCls() { // Set the scaling to normal dwMemClsScaleFactor = 100; // Init the allocators HRESULT hr = S_OK; ACACHE_INIT(C449Cookie, PER_TEMPLATE_CACHE_MAX/4, hr) ACACHE_INIT(C449File, PER_TEMPLATE_CACHE_MAX/4, hr) ACACHE_INIT(CASEElem, PER_SCRPTENG_CACHE_MAX, hr) ACACHE_INIT(CActiveScriptEngine, PER_SCRPTENG_CACHE_MAX, hr) ACACHE_INIT_EX(CAppln, PER_APPLN_CACHE_MAX, FALSE, hr) ACACHE_INIT(CApplnVariants, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CASPError, PER_RESPONSE_BUFFER_MAX,hr) ACACHE_INIT(CClCert, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CComponentCollection, PER_SESSION_CACHE_MAX, hr) ACACHE_INIT(CComponentObject, 2*PER_SESSION_CACHE_MAX, hr) ACACHE_INIT(CCookie, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CDebugResponseBuffer, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CEngineDispElem, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CFileApplnList, 2*PER_APPLN_CACHE_MAX, hr) ACACHE_INIT(CHitObj, PER_QUEUEITEM_CACHE_MAX,hr) ACACHE_INIT(CHTTPHeader, 2*PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CIsapiReqInfo, PER_QUEUEITEM_CACHE_MAX,hr) ACACHE_INIT(CPageComponentManager, PER_QUEUEITEM_CACHE_MAX,hr) ACACHE_INIT(CPageObject, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CRequest, PER_SESSION_CACHE_MAX, hr) ACACHE_INIT(CRequestData, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CRequestHit, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CResponse, PER_SESSION_CACHE_MAX, hr) ACACHE_INIT(CResponseBuffer, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CResponseData, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CScriptingContext, PER_SESSION_CACHE_MAX, hr) ACACHE_INIT(CScriptingNamespace, PER_SESSION_CACHE_MAX, hr) ACACHE_INIT(CServer, PER_SESSION_CACHE_MAX, hr) ACACHE_INIT(CServerData, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT_EX(CSession, PER_SESSION_CACHE_MAX, FALSE, hr) ACACHE_INIT(CSessionVariants, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CStringList, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CStringListElem, 2*PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CTemplate, PER_TEMPLATE_CACHE_MAX, hr) // ACACHE_INIT(CTemplate::CBuffer, PER_TEMPLATE_CACHE_MAX, hr) ACACHE_INIT(CTemplate::CFileMap, PER_TEMPLATE_CACHE_MAX, hr) ACACHE_INIT(CTypelibCacheEntry, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CVariantsIterator, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CViperActivity, PER_REQUEST_CACHE_MAX, hr) ACACHE_INIT(CViperAsyncRequest, PER_QUEUEITEM_CACHE_MAX,hr) ACACHE_FSA_INIT(MemBlock128, 128, PER_SIZE_BUFFER_MAX, hr) ACACHE_FSA_INIT(MemBlock256, 256, PER_SIZE_BUFFER_MAX, hr) ACACHE_FSA_INIT(ResponseBuffer, RESPONSE_BUFFER_SIZE, PER_RESPONSE_BUFFER_MAX, hr) #ifdef DBG unlink(SZ_MEMCLS_LOG_FILE); DebugFilePrintf ( SZ_MEMCLS_LOG_FILE, "MEMCLS: ATQ allocation cache inited with HRESULT=%08x.\n", hr ); #endif return hr; } /*=================================================================== UnInitMemCls To be called from DllInit(). Deletes per-class ATQ memory allocators. For each class with ACACHE_INCLASS_DEFINITIONS() inside add here ACACHE_UNINIT macro. For each ACACHE_FSA_DEFINITION() add here ACACHE_FSA_UNINIT macro. Parameters Returns: HRESULT ===================================================================*/ HRESULT UnInitMemCls() { #ifdef DBG gs_cTotalObjectsLeaked = 0; #endif DEBUG_ACACHE_UNINIT(C449Cookie) DEBUG_ACACHE_UNINIT(C449File) DEBUG_ACACHE_UNINIT(CASEElem) DEBUG_ACACHE_UNINIT(CActiveScriptEngine) DEBUG_ACACHE_UNINIT(CAppln) DEBUG_ACACHE_UNINIT(CApplnVariants) DEBUG_ACACHE_UNINIT(CASPError) DEBUG_ACACHE_UNINIT(CClCert) DEBUG_ACACHE_UNINIT(CComponentCollection) DEBUG_ACACHE_UNINIT(CComponentObject) DEBUG_ACACHE_UNINIT(CCookie) DEBUG_ACACHE_UNINIT(CDebugResponseBuffer) DEBUG_ACACHE_UNINIT(CEngineDispElem) DEBUG_ACACHE_UNINIT(CFileApplnList) DEBUG_ACACHE_UNINIT(CHitObj) DEBUG_ACACHE_UNINIT(CHTTPHeader) DEBUG_ACACHE_UNINIT(CIsapiReqInfo) DEBUG_ACACHE_UNINIT(CPageComponentManager) DEBUG_ACACHE_UNINIT(CPageObject) DEBUG_ACACHE_UNINIT(CRequest) DEBUG_ACACHE_UNINIT(CRequestData) DEBUG_ACACHE_UNINIT(CRequestHit) DEBUG_ACACHE_UNINIT(CResponse) DEBUG_ACACHE_UNINIT(CResponseBuffer) DEBUG_ACACHE_UNINIT(CResponseData) DEBUG_ACACHE_UNINIT(CScriptingNamespace) DEBUG_ACACHE_UNINIT(CScriptingContext) DEBUG_ACACHE_UNINIT(CServer) DEBUG_ACACHE_UNINIT(CServerData) DEBUG_ACACHE_UNINIT(CSession) DEBUG_ACACHE_UNINIT(CSessionVariants) DEBUG_ACACHE_UNINIT(CStringList) DEBUG_ACACHE_UNINIT(CStringListElem) DEBUG_ACACHE_UNINIT(CTemplate) // DEBUG_ACACHE_UNINIT(CTemplate::CBuffer) DEBUG_ACACHE_UNINIT(CTemplate::CFileMap) DEBUG_ACACHE_UNINIT(CTypelibCacheEntry) DEBUG_ACACHE_UNINIT(CVariantsIterator) DEBUG_ACACHE_UNINIT(CViperActivity) DEBUG_ACACHE_UNINIT(CViperAsyncRequest) DEBUG_ACACHE_FSA_UNINIT(MemBlock128) DEBUG_ACACHE_FSA_UNINIT(MemBlock256) DEBUG_ACACHE_FSA_UNINIT(ResponseBuffer) #ifdef DBG DebugFilePrintf ( SZ_MEMCLS_LOG_FILE, "MEMCLS: ATQ allocation cache uninited.\n" "MEMCLS: Total of %d ASP objects leaked.\n", gs_cTotalObjectsLeaked ); #endif return S_OK; }