Leaked source code of windows server 2003
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

  1. //-----------------------------------------------------------------------------
  2. //
  3. //
  4. // File: aqreg.cpp
  5. //
  6. // Description:
  7. //
  8. // Author: Mike Swafford (MikeSwa)
  9. //
  10. // History:
  11. // 1/21/2000 - MikeSwa Created
  12. //
  13. // Copyright (C) 2000 Microsoft Corporation
  14. //
  15. //-----------------------------------------------------------------------------
  16. #include "aqprecmp.h"
  17. #include <registry.h>
  18. //---[ CAQRegDwordDescriptor ]-------------------------------------------------
  19. //
  20. //
  21. // Description:
  22. // Simple stucture used to match the name of a value of a DWORD in memory
  23. // Hungarian:
  24. // regdw, pregwd
  25. //
  26. //-----------------------------------------------------------------------------
  27. class CAQRegDwordDescriptor
  28. {
  29. public:
  30. LPCSTR m_szName;
  31. DWORD *m_pdwValue;
  32. VOID UpdateGlobalDwordFromRegistry(const CMyRegKey &regKey) const;
  33. };
  34. //
  35. // Array of descriptors that match the name of the value with the internal
  36. // variable
  37. //
  38. const CAQRegDwordDescriptor g_rgregwd[] = {
  39. {"MsgHandleThreshold", &g_cMaxIMsgHandlesThreshold},
  40. {"MsgHandleAsyncThreshold", &g_cMaxIMsgHandlesAsyncThreshold},
  41. {"LocalRetryMinutes", &g_cLocalRetryMinutes},
  42. {"CatRetryMinutes", &g_cCatRetryMinutes},
  43. {"RoutingRetryMinutes", &g_cRoutingRetryMinutes},
  44. {"SubmissionRetryMinutes", &g_cSubmissionRetryMinutes},
  45. {"ResetRoutesRetryMinutes", &g_cResetRoutesRetryMinutes},
  46. {"SecondsPerDSNPass", &g_cMaxSecondsPerDSNsGenerationPass},
  47. {"AdditionalPoolThreadsPerProc", &g_cPerProcMaxThreadPoolModifier},
  48. {"MaxPercentPoolThreads", &g_cMaxATQPercent},
  49. {"MaxTicksPerATQThread", &g_cMaxTicksPerATQThread},
  50. {"ResetMessageStatus", &g_fResetMessageStatus},
  51. {"GlitchRetrySeconds", &g_dwGlitchRetrySeconds},
  52. {"MaxPendingCat", &g_cMaxPendingCat},
  53. {"MaxPendingLocal", &g_cMaxPendingLocal},
  54. {"MsgHandleThresholdRangePercentage", &g_cMaxIMsgHandlesThresholdRangePercent},
  55. {"MaxHandleReserve", &g_cMaxHandleReserve},
  56. {"MaxSyncCatQThreads", &g_cMaxSyncCatQThreads},
  57. {"ItemsPerAsyncCatQThread", &g_cItemsPerCatQAsyncThread},
  58. {"ItemsPerSyncCatQThread", &g_cItemsPerCatQSyncThread},
  59. {"MaxSyncLocalQThreads", &g_cMaxSyncLocalQThreads},
  60. {"ItemsPerAsyncLocalQThread", &g_cItemsPerLocalQAsyncThread},
  61. {"ItemsPerSyncLocalQThread", &g_cItemsPerLocalQSyncThread},
  62. {"ItemsPerPostDSNQAsyncThread", &g_cItemsPerPostDSNQAsyncThread},
  63. {"ItemsPerRoutingQAsyncThread", &g_cItemsPerRoutingQAsyncThread},
  64. {"ItemsPerSubmitQAsyncThread", &g_cItemsPerSubmitQAsyncThread},
  65. {"ItemsPerWorkQAsyncThread", &g_cItemsPerWorkQAsyncThread},
  66. {"MaxDSNSize", &g_dwMaxDSNSize},
  67. {"PerMsgFailuresBeforeMarkingAsProblem", &g_cMsgFailuresBeforeMarkingMsgAsProblem},
  68. };
  69. // Key to enable test settings array below
  70. const CAQRegDwordDescriptor g_regwdEnableTestSettings =
  71. {"EnableTestSettings", &g_fEnableTestSettings};
  72. //
  73. // Second Array of values to be enabled only when "EnableTestSettings"
  74. // is set to TRUE
  75. //
  76. const CAQRegDwordDescriptor g_rgregwdTestSettings[] = {
  77. {"PreSubmitQueueFailurePercent", &g_cPreSubmitQueueFailurePercent},
  78. {"PreRoutingQueueFailurePercent", &g_cPreRoutingQueueFailurePercent},
  79. {"PreCatQueueFailurePercent", &g_cPreCatQueueFailurePercent},
  80. {"SubmitQueueSleepMilliseconds", &g_dwSubmitQueueSleepMilliseconds},
  81. {"CatQueueSleepMilliseconds", &g_dwCatQueueSleepMilliseconds},
  82. {"RoutingQueueSleepMilliseconds", &g_dwRoutingQueueSleepMilliseconds},
  83. {"LocalQueueSleepMilliseconds", &g_dwLocalQueueSleepMilliseconds},
  84. {"DelayLinkRemovalSeconds", &g_cDelayLinkRemovalSeconds},
  85. {"EnableRetailAsserts", &g_fEnableRetailAsserts},
  86. };
  87. // Max message objects. This key is slightly special in that it is read
  88. // from a mailmsg configuration key.
  89. const CAQRegDwordDescriptor g_regwdMaxMessageObjects =
  90. {"MaxMessageObjects", &g_cMaxMsgObjects};
  91. //---[ UpdateGlobalDwordFromRegistry ]-----------------------------------------
  92. //
  93. //
  94. // Description:
  95. // Updates a global DWORD value from the registry. Will not modify data
  96. // if the value is not in the registry
  97. // Parameters:
  98. // IN regKey CMyRegKey class for containing key
  99. // IN szValue Name of value to read under key
  100. // IN pdwData Data of value
  101. // Returns:
  102. // -
  103. // History:
  104. // 1/21/2000 - MikeSwa Created
  105. //
  106. //-----------------------------------------------------------------------------
  107. VOID CAQRegDwordDescriptor::UpdateGlobalDwordFromRegistry(const CMyRegKey &regKey) const
  108. {
  109. TraceFunctEnterEx(0, "UpdateGlobalDwordFromRegistry");
  110. DWORD dwValue = 0;
  111. DWORD dwErr = NO_ERROR;
  112. CRegDWORD regDWHandles(regKey, m_szName);
  113. //
  114. // We should have a valid string associated with this object
  115. //
  116. _ASSERT(m_szName);
  117. dwErr = regDWHandles.QueryErrorStatus();
  118. if (NO_ERROR != dwErr)
  119. goto Exit;
  120. dwErr = regDWHandles.GetDword(&dwValue);
  121. if (NO_ERROR != dwErr)
  122. goto Exit;
  123. if (m_pdwValue)
  124. *m_pdwValue = dwValue;
  125. Exit:
  126. DebugTrace(0, "Reading registry value %s\\%s %d - (err 0x%08X)",
  127. regKey.GetName(), m_szName, dwValue, dwErr);
  128. TraceFunctLeave();
  129. return;
  130. }
  131. //---[ ReadGlobalRegistryConfiguration ]---------------------------------------
  132. //
  133. //
  134. // Description:
  135. // Reads all the global registry configuration.
  136. // Parameters:
  137. // -
  138. // Returns:
  139. // -
  140. // History:
  141. // 1/21/2000 - MikeSwa Created
  142. //
  143. //-----------------------------------------------------------------------------
  144. VOID ReadGlobalRegistryConfiguration()
  145. {
  146. TraceFunctEnterEx(0, "HrReadGlobalRegistryConfiguration");
  147. DWORD dwErr = NO_ERROR;
  148. DWORD cValues = 0;
  149. CAQRegDwordDescriptor *pregdw = NULL;
  150. MEMORYSTATUSEX MemStatus;
  151. // Clear this value so we can tell if the user configured it
  152. g_cMaxIMsgHandlesThreshold = 0;
  153. // Registry Key for Queueing Settings
  154. CMyRegKey regKey(HKEY_LOCAL_MACHINE, &dwErr, AQREG_KEY_CONFIGURATION, KEY_READ);
  155. if (NO_ERROR != dwErr) {
  156. DebugTrace(0, "Opening aqreg key %s failed with - Err 0x%08X",
  157. regKey.GetName(), dwErr);
  158. }
  159. else {
  160. //
  161. // Loop through all our DWORD config and store the global variable
  162. //
  163. cValues = sizeof(g_rgregwd)/sizeof(CAQRegDwordDescriptor);
  164. pregdw = (CAQRegDwordDescriptor *) g_rgregwd;
  165. while (cValues) {
  166. pregdw->UpdateGlobalDwordFromRegistry(regKey);
  167. cValues--;
  168. pregdw++;
  169. }
  170. }
  171. // Registry Key for Test Settings
  172. CMyRegKey regKeyTestSettings(HKEY_LOCAL_MACHINE, &dwErr, AQREG_KEY_CONFIGURATION_TESTSETTINGS, KEY_READ);
  173. if (NO_ERROR != dwErr) {
  174. DebugTrace(0, "Opening aqreg key %s failed with - Err 0x%08X",
  175. regKeyTestSettings.GetName(), dwErr);
  176. }
  177. else {
  178. // Load Test Settings if key "EnableTestSettings" is TRUE
  179. g_regwdEnableTestSettings.UpdateGlobalDwordFromRegistry(regKeyTestSettings);
  180. if (g_fEnableTestSettings) {
  181. //
  182. // Loop through all our DWORD config and store the global variable
  183. //
  184. cValues = sizeof(g_rgregwdTestSettings)/sizeof(CAQRegDwordDescriptor);
  185. pregdw = (CAQRegDwordDescriptor *) g_rgregwdTestSettings;
  186. while (cValues) {
  187. pregdw->UpdateGlobalDwordFromRegistry(regKeyTestSettings);
  188. cValues--;
  189. pregdw++;
  190. }
  191. }
  192. }
  193. // Registry Key for MailMsg Settings
  194. CMyRegKey regKeyMailMsg(HKEY_LOCAL_MACHINE, &dwErr, MAILMSG_KEY_CONFIGURATION, KEY_READ);
  195. if (NO_ERROR != dwErr) {
  196. DebugTrace(0, "Opening aqreg key %s failed with - Err 0x%08X",
  197. regKeyMailMsg.GetName(), dwErr);
  198. }
  199. else {
  200. g_regwdMaxMessageObjects.UpdateGlobalDwordFromRegistry(regKeyMailMsg);
  201. }
  202. //
  203. // Now, special case the MsgHandleThreshold to satisify raid 166958
  204. //
  205. if ( 0 == g_cMaxIMsgHandlesThreshold ) {
  206. g_cMaxIMsgHandlesThreshold = 1000;
  207. MemStatus.dwLength = sizeof( MEMORYSTATUSEX );
  208. if ( TRUE == GlobalMemoryStatusEx( &MemStatus ) ) {
  209. ULONG MemBlocks = ( ULONG )( ( ( ( MemStatus.ullTotalPhys >> 10 ) + 512) >> 10 ) / 256 );
  210. if ( 0 == MemBlocks ) {
  211. MemBlocks = 1;
  212. } else if ( 16 < MemBlocks ) {
  213. MemBlocks = 16;
  214. }
  215. g_cMaxIMsgHandlesThreshold = MemBlocks * 1000;
  216. } else {
  217. DebugTrace( 0,
  218. "Getting global memory status failed - (err 0x%08X)",
  219. GetLastError( ) );
  220. }
  221. }
  222. //
  223. // Calculate high and low thresholds
  224. //
  225. if (g_cMaxIMsgHandlesThresholdRangePercent > 99)
  226. g_cMaxIMsgHandlesThresholdRangePercent = 99;
  227. g_cMaxIMsgHandlesLowThreshold = g_cMaxIMsgHandlesThreshold;
  228. if (0 != g_cMaxIMsgHandlesThresholdRangePercent) {
  229. DWORD dwRange = (g_cMaxIMsgHandlesThreshold*g_cMaxIMsgHandlesThresholdRangePercent)/100;
  230. g_cMaxIMsgHandlesLowThreshold -= dwRange;
  231. }
  232. DebugTrace( 0,
  233. "g_cMaxIMsgHandlesThreshold set to %lu",
  234. g_cMaxIMsgHandlesThreshold );
  235. TraceFunctLeave();
  236. }