You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
273 lines
9.6 KiB
273 lines
9.6 KiB
//-----------------------------------------------------------------------------
|
|
//
|
|
//
|
|
// File: aqreg.cpp
|
|
//
|
|
// Description:
|
|
//
|
|
// Author: Mike Swafford (MikeSwa)
|
|
//
|
|
// History:
|
|
// 1/21/2000 - MikeSwa Created
|
|
//
|
|
// Copyright (C) 2000 Microsoft Corporation
|
|
//
|
|
//-----------------------------------------------------------------------------
|
|
#include "aqprecmp.h"
|
|
#include <registry.h>
|
|
|
|
//---[ 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();
|
|
}
|