Source code of Windows XP (NT5)
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.

449 lines
14 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996 - 1998.
  5. //
  6. // File: wqcache.hxx
  7. //
  8. // Contents: WEB Query cache class
  9. //
  10. // History: 96/Jan/3 DwightKr Created
  11. //
  12. //----------------------------------------------------------------------------
  13. #pragma once
  14. //+---------------------------------------------------------------------------
  15. //
  16. // Class: CWQueryBookmark
  17. //
  18. // Purpose: A bookmark to a specific query
  19. //
  20. // History: 96/Jan/23 DwightKr Created
  21. //
  22. //----------------------------------------------------------------------------
  23. const unsigned cchBookmark = (5+16+8+8); // N-xxxx-xxx-xxx
  24. class CWQueryBookmark
  25. {
  26. public:
  27. CWQueryBookmark( WCHAR const * wcsBookmark );
  28. CWQueryBookmark( BOOL fSequential,
  29. CWQueryItem * pItem,
  30. ULONG ulSequenceNumber,
  31. LONG lRecordNumber );
  32. BOOL IsSequential() const { return _fSequential; }
  33. ULONG GetSequenceNumber() const { return _ulSequenceNumber; }
  34. CWQueryItem const * GetQueryItem() const { return _pItem; }
  35. LONG GetRecordNumber() const { return _lRecordNumber; }
  36. WCHAR const * GetBookmark() const { return _wcsBookmark; }
  37. private:
  38. BOOL _fSequential; // Is this a sequential cursor
  39. CWQueryItem * _pItem; // Address of a query item
  40. ULONG _ulSequenceNumber; // Unique sequence number
  41. LONG _lRecordNumber; // Record number
  42. WCHAR _wcsBookmark[cchBookmark]; // String rep of bookmark
  43. };
  44. //+---------------------------------------------------------------------------
  45. //
  46. // Class: CWQueryCache
  47. //
  48. // Purpose: A list of cached queries
  49. //
  50. // History: 96/Jan/23 DwightKr Created
  51. //
  52. //----------------------------------------------------------------------------
  53. class CWQueryCache : public CDoubleList
  54. {
  55. public:
  56. CWQueryCache();
  57. ~CWQueryCache();
  58. CWQueryItem * CreateOrFindQuery( WCHAR const * wcsIDQFile,
  59. XPtr<CVariableSet> & variableSet,
  60. XPtr<COutputFormat> & outputFormat,
  61. CSecurityIdentity securityIdentity,
  62. BOOL & fAsynchronous );
  63. void DeleteOldQueries();
  64. void Release( CWQueryItem * pItem, BOOL fDecRunningQueries = TRUE );
  65. #if (DBG == 1)
  66. BOOL Internal( CVariableSet & variableSet,
  67. COutputFormat & outputFormat,
  68. CVirtualString & string );
  69. #endif // DBG == 1
  70. void FlushCache();
  71. void AddToCache( CWQueryItem * pItem );
  72. BOOL AddToPendingRequestQueue( EXTENSION_CONTROL_BLOCK *pEcb );
  73. void Shutdown();
  74. void Wakeup()
  75. {
  76. _eventCacheWork.Set(); // wake up thread
  77. }
  78. void IncrementActiveRequests()
  79. {
  80. long x = InterlockedIncrement( & _cActiveRequests );
  81. Win4Assert( 0 != x );
  82. }
  83. void DecrementActiveRequests()
  84. {
  85. long x = InterlockedDecrement( & _cActiveRequests );
  86. Win4Assert( 0xffffffff != x );
  87. }
  88. void IncrementRejectedRequests()
  89. {
  90. InterlockedIncrement( & _cRequestsRejected );
  91. *_pcRequestsRejected = _cRequestsRejected;
  92. }
  93. void UpdatePendingRequestCount();
  94. //
  95. // State
  96. //
  97. ULONG Percent(ULONG num, ULONG den)
  98. { return (den == 0) ? 0:
  99. (ULONG)((((ULONGLONG) num * 100) + (den/2) ) / den); }
  100. ULONG Hits() { return Percent(*_pcCacheHits, *_pcCacheHitsAndMisses); }
  101. ULONG Misses() { return Percent(*_pcCacheMisses, *_pcCacheHitsAndMisses); }
  102. ULONG Running() { return *_pcRunningQueries; }
  103. ULONG Cached() { return *_pcCacheItems; }
  104. ULONG Rejected() { return *_pcRequestsRejected; }
  105. ULONG Total() { return *_pcTotalQueries; }
  106. ULONG QPM() { return *_pcQueriesPerMinute; }
  107. LONG ActiveRequestCount() { return _cActiveRequests; }
  108. unsigned PendingQueryCount() { return _pendingQueue.Count(); }
  109. private:
  110. ULONG GetNextSequenceNumber()
  111. {
  112. InterlockedIncrement( (LONG *) &_ulSequenceNumber );
  113. return _ulSequenceNumber;
  114. }
  115. ULONG GetSequenceNumber()
  116. {
  117. return _ulSequenceNumber;
  118. }
  119. CWQueryItem * FindItem( CWQueryBookmark & bookmark,
  120. LONG lSkipCount,
  121. CSecurityIdentity securityIdentity );
  122. CWQueryItem * FindItem( XPtr<CVariableSet> & variableSet,
  123. XPtr<COutputFormat> & outputFormat,
  124. WCHAR const * wcsIDQFile,
  125. CSecurityIdentity securityIdentity );
  126. CWQueryItem * CreateNewQuery( WCHAR const * wcsIDQFile,
  127. XPtr<CVariableSet> & variableSet,
  128. XPtr<COutputFormat> & outputFormat,
  129. CSecurityIdentity securityIdentity,
  130. BOOL & fAsynchronous );
  131. CWQueryItem * Pop() { return (CWQueryItem *) _Pop(); }
  132. void Push(CWQueryItem * pItem) { _Push( pItem ); }
  133. void LokMoveToFront( CWQueryItem * pItem );
  134. static DWORD WINAPI WatchDogThread( void *self );
  135. void ProcessCacheEvents();
  136. BOOL CheckForCompletedQueries();
  137. BOOL CheckForPendingRequests();
  138. void IncrementRunningQueries()
  139. {
  140. long x = InterlockedIncrement( (LONG *)_pcRunningQueries );
  141. // underflow check
  142. Win4Assert( 0 != x );
  143. }
  144. void DecrementRunningQueries()
  145. {
  146. long x = InterlockedDecrement( (LONG *)_pcRunningQueries );
  147. // underflow check
  148. Win4Assert( 0xffffffff != x );
  149. }
  150. void Remove( CWQueryItem * pItem );
  151. #if (DBG == 1)
  152. void Dump( CVirtualString & string,
  153. CVariableSet & variableSet,
  154. COutputFormat & outputFormat );
  155. #endif // DBG == 1
  156. ULONG _ulSignature; // Signature of start of privates
  157. ULONG _ulSequenceNumber; // Sequence # of each query issued
  158. ULONG * _pcCacheItems; // Number of items in cache
  159. ULONG * _pcCacheHits; // Number of cache hits
  160. ULONG * _pcCacheMisses; // Number of cache misses
  161. ULONG * _pcCacheHitsAndMisses; // Sum of hits and misses
  162. ULONG * _pcRunningQueries; // Number of running queries
  163. ULONG * _pcTotalQueries; // Number of new queries
  164. ULONG * _pcRequestsQueued; // current # of queued requests
  165. ULONG * _pcRequestsRejected; // total # of rejected requests
  166. ULONG * _pcQueriesPerMinute; // Queries / min. ~15 second average.
  167. LONG _cActiveRequests; // current # of active isapi requests
  168. LONG _cRequestsRejected; // total # of rejected isapi requests
  169. CMutexSem _mutex; // To serialize access to list
  170. CMutexSem _mutexShutdown; // To serialize access to shutdowns
  171. CEventSem _eventCacheWork; // Wakeup when time do work
  172. CThread _threadWatchDog; // Cache watch dog thread
  173. CIDQFileList _idqFileList; // Cache of parsed idq files
  174. CHTXFileList _htxFileList; // Cache of parsed htx files
  175. CDynArrayInPlace<CWPendingQueryItem *> _pendingQueue;
  176. CNamedSharedMem _smPerf; // Shared memory for perf counters
  177. //
  178. // The "fake" perfcounters to shadow the real ones
  179. //
  180. CI_ISAPI_COUNTERS _smSpare;
  181. };
  182. //+---------------------------------------------------------------------------
  183. //
  184. // Class: CWQueryCacheForwardIter
  185. //
  186. // Purpose: Iterates forward over a CWQueryCache
  187. //
  188. // History: 96/Jan/23 DwightKr Created
  189. //
  190. //----------------------------------------------------------------------------
  191. class CWQueryCacheForwardIter : public CForwardIter
  192. {
  193. public:
  194. CWQueryCacheForwardIter( CWQueryCache & list ) : CForwardIter(list) {}
  195. CWQueryItem * operator->() { return (CWQueryItem *) _pLinkCur; }
  196. CWQueryItem * Get() { return (CWQueryItem *) _pLinkCur; }
  197. };
  198. void SetupDefaultCiVariables( CVariableSet & variableSet );
  199. void SetupDefaultISAPIVariables( CVariableSet & variableSet );
  200. //+---------------------------------------------------------------------------
  201. //
  202. // Class: CWQueryCacheBackwardIter
  203. //
  204. // Purpose: Iterates backwards over a CWQueryCache
  205. //
  206. // History: 96/Jan/23 DwightKr Created
  207. //
  208. //----------------------------------------------------------------------------
  209. class CWQueryCacheBackwardIter : public CBackwardIter
  210. {
  211. public:
  212. CWQueryCacheBackwardIter( CWQueryCache & list ) : CBackwardIter(list) {}
  213. CWQueryItem * operator->() { return (CWQueryItem *) _pLinkCur; }
  214. CWQueryItem * Get() { return (CWQueryItem *) _pLinkCur; }
  215. };
  216. //+---------------------------------------------------------------------------
  217. //
  218. // Class: CICommandItem
  219. //
  220. // Purpose: Info for an ICommand cache entry
  221. //
  222. // History: 97/Feb/23 dlee Created
  223. //
  224. //----------------------------------------------------------------------------
  225. class CICommandItem
  226. {
  227. public:
  228. BOOL fInUse;
  229. XInterface<ICommand> xCommand;
  230. DWORD depth;
  231. XArray<WCHAR> aMachine;
  232. XArray<WCHAR> aCatalog;
  233. XArray<WCHAR> aScope;
  234. };
  235. //+---------------------------------------------------------------------------
  236. //
  237. // Class: CICommandCache
  238. //
  239. // Purpose: A cache for ICommands, since they are expensive to create
  240. //
  241. // History: 97/Feb/23 dlee Created
  242. //
  243. //----------------------------------------------------------------------------
  244. class CICommandCache
  245. {
  246. public:
  247. CICommandCache();
  248. SCODE Make( ICommand ** ppCommand,
  249. DWORD depth,
  250. WCHAR const * pwcMachine,
  251. WCHAR const * pwcCatalog,
  252. WCHAR const * pwcScope );
  253. void Release( ICommand * pCommand );
  254. void Remove( ICommand * pCommand );
  255. void Purge();
  256. private:
  257. SCODE ParseAndMake( ICommand ** ppCommand,
  258. DWORD depth,
  259. WCHAR const * pwcMachine,
  260. WCHAR const * pwcCatalog,
  261. WCHAR const * pwcScope );
  262. ULONG _ulSig;
  263. CMutexSem _mutex;
  264. XArray<CICommandItem> _aItems;
  265. XInterface<ISimpleCommandCreator> xCmdCreator;
  266. };
  267. //+---------------------------------------------------------------------------
  268. //
  269. // Function: CopyString
  270. //
  271. // Purpose: Simple method to allocate and copy a string (strdup)
  272. //
  273. // History: 99-Feb-10 dlee Created
  274. //
  275. //----------------------------------------------------------------------------
  276. inline WCHAR * CopyString( WCHAR const *pwc )
  277. {
  278. unsigned c = wcslen( pwc ) + 1;
  279. WCHAR *pwcNew = new WCHAR[c];
  280. RtlCopyMemory( pwcNew, pwc, c * sizeof WCHAR );
  281. return pwcNew;
  282. } //CopyString
  283. //+---------------------------------------------------------------------------
  284. //
  285. // Class: CFormatItem
  286. //
  287. // Purpose: Formatting information for a given locale
  288. //
  289. // History: 99-Feb-10 dlee Created
  290. //
  291. //----------------------------------------------------------------------------
  292. class CFormatItem
  293. {
  294. public:
  295. CFormatItem( LCID lcid );
  296. ~CFormatItem();
  297. void Copy( NUMBERFMT & numberFormat, CURRENCYFMT & currencyFormat ) const;
  298. LCID GetLCID() const { return _lcid; }
  299. private:
  300. LCID _lcid;
  301. NUMBERFMT _numberFormat;
  302. CURRENCYFMT _currencyFormat;
  303. };
  304. //+---------------------------------------------------------------------------
  305. //
  306. // Class: CFormattingCache
  307. //
  308. // Purpose: Cache of formatting information.
  309. //
  310. // History: 99-Feb-10 dlee Created
  311. //
  312. //----------------------------------------------------------------------------
  313. class CFormattingCache
  314. {
  315. public:
  316. CFormattingCache() {}
  317. void GetFormattingInfo( LCID lcid,
  318. NUMBERFMT & numberFormat,
  319. CURRENCYFMT & currencyFormat );
  320. void Purge();
  321. private:
  322. CMutexSem _mutex;
  323. CCountedDynArray<CFormatItem> _aItems;
  324. };
  325. class CTheGlobalIDQVariables;
  326. extern CTheGlobalIDQVariables * pTheGlobalIDQVariables;
  327. class CIDQTheFirst
  328. {
  329. public:
  330. CIDQTheFirst( CTheGlobalIDQVariables *p )
  331. {
  332. pTheGlobalIDQVariables = p;
  333. }
  334. };
  335. class CTheGlobalIDQVariables
  336. {
  337. public:
  338. CTheGlobalIDQVariables() :
  339. #pragma warning(disable : 4355) // 'this' in a constructor
  340. _first(this),
  341. #pragma warning(default : 4355) // 'this' in a constructor
  342. _fTheWebActiveXSearchShutdown(FALSE)
  343. {
  344. }
  345. CIDQTheFirst _first;
  346. BOOL _fTheWebActiveXSearchShutdown;
  347. CIdqRegParams _TheIDQRegParams;
  348. CICommandCache _TheICommandCache;
  349. CWebResourceArbiter _TheWebResourceArbiter;
  350. CWebPendingQueue _TheWebPendingRequestQueue;
  351. CWQueryCache _TheWebQueryCache;
  352. CFormattingCache _TheFormattingCache;
  353. };
  354. #define TheGlobalIDQVariables (*pTheGlobalIDQVariables)
  355. #define TheIDQRegParams TheGlobalIDQVariables._TheIDQRegParams
  356. #define TheWebQueryCache TheGlobalIDQVariables._TheWebQueryCache
  357. #define TheWebPendingRequestQueue TheGlobalIDQVariables._TheWebPendingRequestQueue
  358. #define TheWebResourceArbiter TheGlobalIDQVariables._TheWebResourceArbiter
  359. #define fTheActiveXSearchShutdown TheGlobalIDQVariables._fTheWebActiveXSearchShutdown
  360. #define TheICommandCache TheGlobalIDQVariables._TheICommandCache
  361. #define TheFormattingCache TheGlobalIDQVariables._TheFormattingCache