//----------------------------------------------------------------------------- // // // File: aqreg.cpp // // Description: // // Author: Mike Swafford (MikeSwa) // // History: // 1/21/2000 - MikeSwa Created // // Copyright (C) 2000 Microsoft Corporation // //----------------------------------------------------------------------------- #include "aqprecmp.h" #include //---[ CAQRegDwordDescriptor ]------------------------------------------------- // // // Description: // Simple stucture used to match the name of a value of a DWORD in memory // Hungarian: // regdw, pregwd // //----------------------------------------------------------------------------- class CAQRegDwordDescriptor { public: LPCSTR m_szName; DWORD *m_pdwValue; VOID UpdateGlobalDwordFromRegistry(const CMyRegKey ®Key) const; }; // // Array of descriptors that match the name of the value with the internal // variable // const CAQRegDwordDescriptor g_rgregwd[] = { {"MsgHandleThreshold", &g_cMaxIMsgHandlesThreshold}, {"MsgHandleAsyncThreshold", &g_cMaxIMsgHandlesAsyncThreshold}, {"LocalRetryMinutes", &g_cLocalRetryMinutes}, {"CatRetryMinutes", &g_cCatRetryMinutes}, {"RoutingRetryMinutes", &g_cRoutingRetryMinutes}, {"SubmissionRetryMinutes", &g_cSubmissionRetryMinutes}, {"ResetRoutesRetryMinutes", &g_cResetRoutesRetryMinutes}, {"SecondsPerDSNPass", &g_cMaxSecondsPerDSNsGenerationPass}, {"AdditionalPoolThreadsPerProc", &g_cPerProcMaxThreadPoolModifier}, {"MaxPercentPoolThreads", &g_cMaxATQPercent}, {"MaxTicksPerATQThread", &g_cMaxTicksPerATQThread}, {"ResetMessageStatus", &g_fResetMessageStatus}, {"GlitchRetrySeconds", &g_dwGlitchRetrySeconds}, {"MaxPendingCat", &g_cMaxPendingCat}, {"MaxPendingLocal", &g_cMaxPendingLocal}, {"MsgHandleThresholdRangePercentage", &g_cMaxIMsgHandlesThresholdRangePercent}, {"MaxHandleReserve", &g_cMaxHandleReserve}, {"MaxSyncCatQThreads", &g_cMaxSyncCatQThreads}, {"ItemsPerAsyncCatQThread", &g_cItemsPerCatQAsyncThread}, {"ItemsPerSyncCatQThread", &g_cItemsPerCatQSyncThread}, {"MaxSyncLocalQThreads", &g_cMaxSyncLocalQThreads}, {"ItemsPerAsyncLocalQThread", &g_cItemsPerLocalQAsyncThread}, {"ItemsPerSyncLocalQThread", &g_cItemsPerLocalQSyncThread}, {"ItemsPerPostDSNQAsyncThread", &g_cItemsPerPostDSNQAsyncThread}, {"ItemsPerRoutingQAsyncThread", &g_cItemsPerRoutingQAsyncThread}, {"ItemsPerSubmitQAsyncThread", &g_cItemsPerSubmitQAsyncThread}, {"ItemsPerWorkQAsyncThread", &g_cItemsPerWorkQAsyncThread}, {"MaxDSNSize", &g_dwMaxDSNSize}, {"PerMsgFailuresBeforeMarkingAsProblem", &g_cMsgFailuresBeforeMarkingMsgAsProblem}, }; // Key to enable test settings array below const CAQRegDwordDescriptor g_regwdEnableTestSettings = {"EnableTestSettings", &g_fEnableTestSettings}; // // Second Array of values to be enabled only when "EnableTestSettings" // is set to TRUE // const CAQRegDwordDescriptor g_rgregwdTestSettings[] = { {"PreSubmitQueueFailurePercent", &g_cPreSubmitQueueFailurePercent}, {"PreRoutingQueueFailurePercent", &g_cPreRoutingQueueFailurePercent}, {"PreCatQueueFailurePercent", &g_cPreCatQueueFailurePercent}, {"SubmitQueueSleepMilliseconds", &g_dwSubmitQueueSleepMilliseconds}, {"CatQueueSleepMilliseconds", &g_dwCatQueueSleepMilliseconds}, {"RoutingQueueSleepMilliseconds", &g_dwRoutingQueueSleepMilliseconds}, {"LocalQueueSleepMilliseconds", &g_dwLocalQueueSleepMilliseconds}, {"DelayLinkRemovalSeconds", &g_cDelayLinkRemovalSeconds}, {"EnableRetailAsserts", &g_fEnableRetailAsserts}, }; // Max message objects. This key is slightly special in that it is read // from a mailmsg configuration key. const CAQRegDwordDescriptor g_regwdMaxMessageObjects = {"MaxMessageObjects", &g_cMaxMsgObjects}; //---[ UpdateGlobalDwordFromRegistry ]----------------------------------------- // // // Description: // Updates a global DWORD value from the registry. Will not modify data // if the value is not in the registry // Parameters: // IN regKey CMyRegKey class for containing key // IN szValue Name of value to read under key // IN pdwData Data of value // Returns: // - // History: // 1/21/2000 - MikeSwa Created // //----------------------------------------------------------------------------- VOID CAQRegDwordDescriptor::UpdateGlobalDwordFromRegistry(const CMyRegKey ®Key) const { TraceFunctEnterEx(0, "UpdateGlobalDwordFromRegistry"); DWORD dwValue = 0; DWORD dwErr = NO_ERROR; CRegDWORD regDWHandles(regKey, m_szName); // // We should have a valid string associated with this object // _ASSERT(m_szName); dwErr = regDWHandles.QueryErrorStatus(); if (NO_ERROR != dwErr) goto Exit; dwErr = regDWHandles.GetDword(&dwValue); if (NO_ERROR != dwErr) goto Exit; if (m_pdwValue) *m_pdwValue = dwValue; Exit: DebugTrace(0, "Reading registry value %s\\%s %d - (err 0x%08X)", regKey.GetName(), m_szName, dwValue, dwErr); TraceFunctLeave(); return; } //---[ ReadGlobalRegistryConfiguration ]--------------------------------------- // // // Description: // Reads all the global registry configuration. // Parameters: // - // Returns: // - // History: // 1/21/2000 - MikeSwa Created // //----------------------------------------------------------------------------- VOID ReadGlobalRegistryConfiguration() { TraceFunctEnterEx(0, "HrReadGlobalRegistryConfiguration"); DWORD dwErr = NO_ERROR; DWORD cValues = 0; CAQRegDwordDescriptor *pregdw = NULL; MEMORYSTATUSEX MemStatus; // Clear this value so we can tell if the user configured it g_cMaxIMsgHandlesThreshold = 0; // Registry Key for Queueing Settings CMyRegKey regKey(HKEY_LOCAL_MACHINE, &dwErr, AQREG_KEY_CONFIGURATION, KEY_READ); if (NO_ERROR != dwErr) { DebugTrace(0, "Opening aqreg key %s failed with - Err 0x%08X", regKey.GetName(), dwErr); } else { // // Loop through all our DWORD config and store the global variable // cValues = sizeof(g_rgregwd)/sizeof(CAQRegDwordDescriptor); pregdw = (CAQRegDwordDescriptor *) g_rgregwd; while (cValues) { pregdw->UpdateGlobalDwordFromRegistry(regKey); cValues--; pregdw++; } } // Registry Key for Test Settings CMyRegKey regKeyTestSettings(HKEY_LOCAL_MACHINE, &dwErr, AQREG_KEY_CONFIGURATION_TESTSETTINGS, KEY_READ); if (NO_ERROR != dwErr) { DebugTrace(0, "Opening aqreg key %s failed with - Err 0x%08X", regKeyTestSettings.GetName(), dwErr); } else { // Load Test Settings if key "EnableTestSettings" is TRUE g_regwdEnableTestSettings.UpdateGlobalDwordFromRegistry(regKeyTestSettings); if (g_fEnableTestSettings) { // // Loop through all our DWORD config and store the global variable // cValues = sizeof(g_rgregwdTestSettings)/sizeof(CAQRegDwordDescriptor); pregdw = (CAQRegDwordDescriptor *) g_rgregwdTestSettings; while (cValues) { pregdw->UpdateGlobalDwordFromRegistry(regKeyTestSettings); cValues--; pregdw++; } } } // Registry Key for MailMsg Settings CMyRegKey regKeyMailMsg(HKEY_LOCAL_MACHINE, &dwErr, MAILMSG_KEY_CONFIGURATION, KEY_READ); if (NO_ERROR != dwErr) { DebugTrace(0, "Opening aqreg key %s failed with - Err 0x%08X", regKeyMailMsg.GetName(), dwErr); } else { g_regwdMaxMessageObjects.UpdateGlobalDwordFromRegistry(regKeyMailMsg); } // // Now, special case the MsgHandleThreshold to satisify raid 166958 // if ( 0 == g_cMaxIMsgHandlesThreshold ) { g_cMaxIMsgHandlesThreshold = 1000; MemStatus.dwLength = sizeof( MEMORYSTATUSEX ); if ( TRUE == GlobalMemoryStatusEx( &MemStatus ) ) { ULONG MemBlocks = ( ULONG )( ( ( ( MemStatus.ullTotalPhys >> 10 ) + 512) >> 10 ) / 256 ); if ( 0 == MemBlocks ) { MemBlocks = 1; } else if ( 16 < MemBlocks ) { MemBlocks = 16; } g_cMaxIMsgHandlesThreshold = MemBlocks * 1000; } else { DebugTrace( 0, "Getting global memory status failed - (err 0x%08X)", GetLastError( ) ); } } // // Calculate high and low thresholds // if (g_cMaxIMsgHandlesThresholdRangePercent > 99) g_cMaxIMsgHandlesThresholdRangePercent = 99; g_cMaxIMsgHandlesLowThreshold = g_cMaxIMsgHandlesThreshold; if (0 != g_cMaxIMsgHandlesThresholdRangePercent) { DWORD dwRange = (g_cMaxIMsgHandlesThreshold*g_cMaxIMsgHandlesThresholdRangePercent)/100; g_cMaxIMsgHandlesLowThreshold -= dwRange; } DebugTrace( 0, "g_cMaxIMsgHandlesThreshold set to %lu", g_cMaxIMsgHandlesThreshold ); TraceFunctLeave(); }