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.

905 lines
19 KiB

  1. /**********************************************************************/
  2. /** Microsoft Windows NT **/
  3. /** Copyright(c) Microsoft Corp., 1998 **/
  4. /**********************************************************************/
  5. /*
  6. filecach.cxx
  7. This module implements the private interface to the file cache
  8. FILE HISTORY:
  9. MCourage 09-Dec-1997 Created
  10. */
  11. #include "tsunamip.hxx"
  12. #include <tsunami.hxx>
  13. #include "filecach.hxx"
  14. #include "filehash.hxx"
  15. #include "tlcach.h"
  16. #include <dbgutil.h>
  17. /*
  18. * Globals
  19. */
  20. CFileHashTable * g_pFileInfoTable;
  21. CFileCacheStats * g_pFileCacheStats;
  22. HANDLE g_hFileCacheShutdownEvent;
  23. BOOL g_fFileCacheShutdown;
  24. CRITICAL_SECTION g_csUriInfo;
  25. #if TSUNAMI_REF_DEBUG
  26. PTRACE_LOG g_pFileRefTraceLog;
  27. #endif
  28. /*
  29. * Private helper function declarations
  30. */
  31. inline VOID I_DerefFileInfo(TS_OPEN_FILE_INFO *pOpenFile);
  32. VOID I_AddRefIO(TS_OPEN_FILE_INFO *pOpenFile);
  33. VOID I_DerefIO(TS_OPEN_FILE_INFO *pOpenFile);
  34. BOOL FileFlushFilterAll(TS_OPEN_FILE_INFO *pOpenFile, PVOID pv);
  35. /*
  36. * function definitions
  37. */
  38. BOOL
  39. FileCache_Initialize(
  40. IN DWORD dwMaxFiles
  41. )
  42. {
  43. BOOL fReturn;
  44. #if TSUNAMI_REF_DEBUG
  45. g_pFileRefTraceLog = CreateRefTraceLog(
  46. 256, // LogSize
  47. 0 // ExtraBytesInHeader
  48. );
  49. #endif // TSUNAMI_REF_DEBUG
  50. g_pFileInfoTable = new CFileHashTable("FCinfo");
  51. g_pFileCacheStats = new CFileCacheStats;
  52. g_fFileCacheShutdown = FALSE;
  53. g_hFileCacheShutdownEvent = CreateEvent(NULL, TRUE, FALSE, NULL);
  54. INITIALIZE_CRITICAL_SECTION( &g_csUriInfo );
  55. if (g_bEnableSequentialRead) {
  56. TsCreateFileFlags |= FILE_FLAG_SEQUENTIAL_SCAN;
  57. }
  58. fReturn = (g_pFileInfoTable
  59. && g_pFileCacheStats
  60. && TS_OPEN_FILE_INFO::Initialize(dwMaxFiles)
  61. && (InitializeTwoLevelCache(g_dwMemCacheSize) == ERROR_SUCCESS)
  62. && g_hFileCacheShutdownEvent);
  63. if (!fReturn) {
  64. FileCache_Terminate();
  65. }
  66. return fReturn;
  67. }
  68. VOID
  69. FileCache_Terminate(
  70. VOID
  71. )
  72. {
  73. g_fFileCacheShutdown = TRUE;
  74. FlushFileCache();
  75. //
  76. // At this point the hash table is empty, but there will still
  77. // be some oplocked files hanging around. We have to wait for
  78. // all the oplock completions before moving on.
  79. //
  80. if (g_pFileCacheStats->GetFlushedEntries()) {
  81. WaitForSingleObject(g_hFileCacheShutdownEvent, TS_FILE_CACHE_SHUTDOWN_TIMEOUT);
  82. DBG_ASSERT( g_pFileCacheStats->GetFlushedEntries() == 0 );
  83. }
  84. DeleteCriticalSection( &g_csUriInfo );
  85. CloseHandle(g_hFileCacheShutdownEvent);
  86. g_hFileCacheShutdownEvent=NULL;
  87. DBG_REQUIRE(TerminateTwoLevelCache() == ERROR_SUCCESS);
  88. TS_OPEN_FILE_INFO::Cleanup();
  89. delete g_pFileInfoTable;
  90. DBGPRINTF(( DBG_CONTEXT,
  91. "FileCache_Terminate: deleted g_pFileInfoTable.\n" ));
  92. delete g_pFileCacheStats;
  93. g_pFileInfoTable = NULL;
  94. g_pFileCacheStats = NULL;
  95. #if TSUNAMI_REF_DEBUG
  96. if( g_pFileRefTraceLog != NULL ) {
  97. DestroyRefTraceLog( g_pFileRefTraceLog );
  98. g_pFileRefTraceLog = NULL;
  99. }
  100. #endif // TSUNAMI_REF_DEBUG
  101. }
  102. DWORD
  103. CacheFile(
  104. IN TS_OPEN_FILE_INFO * pOpenFile,
  105. IN DWORD dwFlags
  106. )
  107. /*++
  108. Routine Description:
  109. Add a file info structure to the cache.
  110. If the FCF_UNINITIALIZED flag is set, the file will be added to
  111. the cache, but calls to CheckoutFile will be blocked until the
  112. file is marked initialized with NotifyFileInitialized.
  113. CheckoutFileEntry will not block. I expect that this flag will
  114. always be set.
  115. The FCF_FOR_IO flag indicates that the caller will be performing
  116. I/O operations with the cached file handle. This flag will be
  117. clear in most cases except in TsCreateFile.
  118. Arguments:
  119. pOpenFile - The structure to be cached.
  120. pstrPath - The pathname that will be used to look up the cache entry.
  121. dwFlags - Valid flags are FCF_UNINITIALIZED and FCF_FOR_IO.
  122. Return Value:
  123. TS_ERROR_SUCCESS
  124. TS_ERROR_OUT_OF_MEMORY
  125. TS_ERROR_ALREADY_CACHED
  126. --*/
  127. {
  128. enum LK_RETCODE lkRetval;
  129. DWORD dwRetval;
  130. DBG_ASSERT( pOpenFile != NULL );
  131. //
  132. // The caller gets a reference to this file info object
  133. //
  134. pOpenFile->AddRef();
  135. //
  136. // Don't need to acquire the lock since the object is not yet
  137. // in the cache.
  138. //
  139. pOpenFile->SetCached();
  140. if (dwFlags & FCF_FOR_IO) {
  141. pOpenFile->AddRefIO();
  142. }
  143. if (! (dwFlags & FCF_UNINITIALIZED)) {
  144. pOpenFile->SetInitialized();
  145. }
  146. //
  147. // Put it in the hash table
  148. //
  149. lkRetval = g_pFileInfoTable->InsertRecord(pOpenFile, false);
  150. if (LK_SUCCESS == lkRetval) {
  151. dwRetval = TS_ERROR_SUCCESS;
  152. g_pFileCacheStats->IncFilesCached();
  153. } else {
  154. if (LK_ALLOC_FAIL == lkRetval) {
  155. dwRetval = TS_ERROR_OUT_OF_MEMORY;
  156. } else if (LK_KEY_EXISTS == lkRetval) {
  157. dwRetval = TS_ERROR_ALREADY_CACHED;
  158. } else {
  159. //
  160. // No other error should come to pass
  161. //
  162. dwRetval = TS_ERROR_OUT_OF_MEMORY;
  163. DBG_ASSERT(FALSE);
  164. }
  165. pOpenFile->ClearCached();
  166. if (dwFlags & FCF_FOR_IO) {
  167. pOpenFile->DerefIO();
  168. }
  169. //
  170. // Remove the reference we added.
  171. // Don't call I_DerefFileInfo, because this
  172. // object never made it to the cache.
  173. // The caller will free the memory.
  174. //
  175. pOpenFile->Deref();
  176. }
  177. return dwRetval;
  178. }
  179. VOID
  180. NotifyInitializedFile(
  181. IN TS_OPEN_FILE_INFO * pOpenFile
  182. )
  183. /*++
  184. Routine Description:
  185. This function tells that cache that a file previously cached with
  186. CacheUninitializedFile, is now ready for use.
  187. Arguments:
  188. pOpenFile - The file which is now initialized.
  189. Return Value:
  190. None.
  191. --*/
  192. {
  193. BOOL bShouldClose;
  194. CHECK_FILE_STATE( pOpenFile );
  195. //
  196. // Mark the file as initialized
  197. //
  198. pOpenFile->Lock();
  199. pOpenFile->SetInitialized();
  200. bShouldClose = pOpenFile->IsCloseable();
  201. pOpenFile->Unlock();
  202. //
  203. // Clean up as neccessary
  204. // Note that I don't have to worry about the IO refcount
  205. // going back up because the file is marked as flushed.
  206. //
  207. if (bShouldClose) {
  208. pOpenFile->CloseHandle();
  209. }
  210. //
  211. // TODO: need to execute any notification code?
  212. //
  213. }
  214. VOID
  215. DecacheFile(
  216. IN TS_OPEN_FILE_INFO * pOpenFile,
  217. IN DWORD dwFlags
  218. )
  219. /*++
  220. Routine Description:
  221. Remove a file info entry from the cache. After a call to
  222. DecacheFile the entry will not be returned by CheckoutFile. The
  223. entry itself is cleaned up when the last CheckinFile occurs.
  224. Calling DecacheFile checks the entry in.
  225. The FCF_FOR_IO flag indicates that the caller will be performing
  226. I/O operations with the cached file handle. I expect that this flag
  227. will always be clear.
  228. Arguments:
  229. pOpenFile - The file info structure to be decached
  230. dwFlags - Valid flags are FCF_FOR_IO, FCF_NO_DEREF.
  231. Return Value:
  232. None.
  233. --*/
  234. {
  235. BOOL bShouldClose;
  236. TS_OPEN_FILE_INFO * pHashFile;
  237. LK_RETCODE lkrc;
  238. CHECK_FILE_STATE( pOpenFile );
  239. //
  240. // remove the file from the hashtable
  241. //
  242. lkrc = g_pFileInfoTable->DeleteRecord(pOpenFile);
  243. DBG_ASSERT( LK_SUCCESS == lkrc || LK_NO_SUCH_KEY == lkrc );
  244. #if TSUNAMI_REF_DEBUG
  245. if (LK_SUCCESS == lkrc) {
  246. pOpenFile->TraceCheckpoint();
  247. }
  248. #endif
  249. //
  250. // update state
  251. //
  252. pOpenFile->Lock();
  253. if (! pOpenFile->IsFlushed() ) {
  254. pOpenFile->SetFlushed();
  255. g_pFileCacheStats->IncFlushedEntries();
  256. g_pFileCacheStats->DecFilesCached();
  257. }
  258. if (dwFlags & FCF_FOR_IO) {
  259. I_DerefIO(pOpenFile);
  260. }
  261. bShouldClose = pOpenFile->IsCloseable();
  262. pOpenFile->Unlock();
  263. //
  264. // Clean up as neccessary
  265. // Note that I don't have to worry about the IO refcount
  266. // going back up because the file is marked as flushed.
  267. //
  268. if (bShouldClose) {
  269. pOpenFile->CloseHandle();
  270. }
  271. if (!(dwFlags & FCF_NO_DEREF)) {
  272. I_DerefFileInfo(pOpenFile);
  273. }
  274. }
  275. VOID
  276. FlushFileCache(
  277. VOID
  278. )
  279. /*++
  280. Routine Description:
  281. Removes all entries from the cache. Unlike DecacheFile, this
  282. function does not check any entries in.
  283. Arguments:
  284. None
  285. Return Value:
  286. None
  287. --*/
  288. {
  289. FilteredFlushFileCache(FileFlushFilterAll, NULL);
  290. }
  291. LK_PREDICATE
  292. FileFlushCachePredicate(
  293. TS_OPEN_FILE_INFO *pOpenFile,
  294. void* pvState
  295. )
  296. {
  297. TS_FILE_FLUSH_STATE * pFlushState = static_cast<TS_FILE_FLUSH_STATE*>(pvState);
  298. LK_PREDICATE lkpAction;
  299. if (pFlushState->pfnFilter(pOpenFile, pFlushState->pvParm)) {
  300. //
  301. // put it on the list
  302. //
  303. pOpenFile->AddRef(); // for the list
  304. InsertHeadList(&pFlushState->ListHead, &pOpenFile->FlushList);
  305. lkpAction = LKP_PERFORM;
  306. } else {
  307. lkpAction = LKP_NO_ACTION;
  308. }
  309. return lkpAction;
  310. }
  311. VOID
  312. FilteredFlushFileCache(
  313. IN PFCFILTERRTN pFilterRoutine,
  314. IN PVOID pv
  315. )
  316. /*++
  317. Routine Description:
  318. Removes entries based on a caller specified filter. The caller
  319. provides a boolean function which takes a cache entry as a
  320. parameter. The function will be called with each item in the cache.
  321. If the function returns TRUE, the item will be decached (but not
  322. checked in). Otherwise the item will remain in the cache.
  323. Arguments:
  324. pFilterRoutine - A pointer to the filter function
  325. pv - a parameter to the filter function
  326. Return Value:
  327. None
  328. --*/
  329. {
  330. TS_FILE_FLUSH_STATE FlushState;
  331. g_pFileCacheStats->IncFlushes();
  332. //
  333. // Initialize the flush state
  334. //
  335. FlushState.pfnFilter = pFilterRoutine;
  336. InitializeListHead(&FlushState.ListHead);
  337. FlushState.pvParm = pv;
  338. //
  339. // Delete elements from table and construct list
  340. //
  341. g_pFileInfoTable->DeleteIf(FileFlushCachePredicate, &FlushState);
  342. //
  343. // Update element state and close file handles
  344. //
  345. PLIST_ENTRY pEntry;
  346. PLIST_ENTRY pNext;
  347. TS_OPEN_FILE_INFO * pOpenFile;
  348. BOOL bShouldClose;
  349. for (pEntry = FlushState.ListHead.Flink;
  350. pEntry != &FlushState.ListHead;
  351. pEntry = pNext ) {
  352. pNext = pEntry->Flink;
  353. pOpenFile = CONTAINING_RECORD( pEntry, TS_OPEN_FILE_INFO, FlushList );
  354. DBG_ASSERT( pOpenFile->CheckSignature() );
  355. pOpenFile->Lock();
  356. if (! pOpenFile->IsFlushed() ) {
  357. pOpenFile->SetFlushed();
  358. g_pFileCacheStats->IncFlushedEntries();
  359. g_pFileCacheStats->DecFilesCached();
  360. }
  361. bShouldClose = pOpenFile->IsCloseable();
  362. pOpenFile->Unlock();
  363. if (bShouldClose) {
  364. pOpenFile->CloseHandle();
  365. }
  366. I_DerefFileInfo(pOpenFile); // remove our list's reference
  367. }
  368. }
  369. BOOL
  370. CheckoutFile(
  371. IN LPCSTR pstrPath,
  372. IN DWORD dwFlags,
  373. OUT TS_OPEN_FILE_INFO ** ppOpenFile
  374. )
  375. /*++
  376. Routine Description:
  377. Look up an entry in the cache and return it.
  378. The FCF_FOR_IO flag indicates that the caller will be performing
  379. I/O operations with the cached file handle. This flag will be clear
  380. in most cases except in TsCreateFile.
  381. Arguments:
  382. pstrPath - The pathname of the desired file info in UPPERCASE!!
  383. dwFlags - The only valid flag is FCF_FOR_IO.
  384. ppOpenFile - On success this output points to the cached entry.
  385. Otherwise it is not set.
  386. Return Value:
  387. TRUE if the item was found, FALSE otherwise.
  388. Additional error information can be obtained from GetLastError()
  389. --*/
  390. {
  391. CFileKey fileKey;
  392. TS_OPEN_FILE_INFO * pOpenFile;
  393. BOOL bRetVal = FALSE;
  394. DWORD dwError;
  395. DBG_ASSERT( pstrPath != NULL );
  396. //
  397. // Look in the hash table
  398. //
  399. fileKey.m_pszFileName = const_cast<char *>(pstrPath);
  400. fileKey.m_cbFileName = strlen(pstrPath);
  401. g_pFileInfoTable->FindKey(&fileKey, &pOpenFile);
  402. if (NULL == pOpenFile) {
  403. dwError = ERROR_FILE_NOT_FOUND;
  404. goto exit;
  405. }
  406. //
  407. // Make sure it's valid and update state
  408. //
  409. CHECK_FILE_STATE( pOpenFile );
  410. pOpenFile->Lock();
  411. DBG_ASSERT( pOpenFile->IsCached() );
  412. if (dwFlags & FCF_FOR_IO) {
  413. I_AddRefIO(pOpenFile);
  414. }
  415. pOpenFile->Unlock();
  416. //
  417. // Make sure it's initialized
  418. //
  419. if (!pOpenFile->IsInitialized()) {
  420. int t = 1; // time to sleep
  421. int i = 0; // number of times we've gone to sleep
  422. while (!pOpenFile->IsInitialized() && i < c_SleepTimeout) {
  423. Sleep(t);
  424. if (t < c_dwSleepmax) {
  425. t <<= 1;
  426. }
  427. i++;
  428. }
  429. }
  430. if (!pOpenFile->IsInitialized()) {
  431. //
  432. // OK we've waited long enough. Just return failure.
  433. //
  434. dwError = ERROR_BUSY;
  435. goto err;
  436. }
  437. if (pOpenFile->IsFlushed()) {
  438. dwError = ERROR_FILE_NOT_FOUND;
  439. goto err;
  440. }
  441. //
  442. // At last, sweet success!
  443. //
  444. bRetVal = TRUE;
  445. *ppOpenFile = pOpenFile;
  446. exit:
  447. if (!bRetVal) {
  448. SetLastError(dwError);
  449. }
  450. if (dwFlags & FCF_FOR_IO) {
  451. if (bRetVal) {
  452. g_pFileCacheStats->IncHits();
  453. } else {
  454. g_pFileCacheStats->IncMisses();
  455. }
  456. }
  457. return bRetVal;
  458. err:
  459. //
  460. // if we added to the IO refcount we have to decrement
  461. // that now.
  462. //
  463. if (dwFlags & FCF_FOR_IO) {
  464. pOpenFile->Lock();
  465. I_DerefIO(pOpenFile);
  466. pOpenFile->Unlock();
  467. }
  468. //
  469. // FindKey automatically increments the refcount so
  470. // we must deref here.
  471. //
  472. I_DerefFileInfo(pOpenFile);
  473. if (dwFlags & FCF_FOR_IO) {
  474. g_pFileCacheStats->IncMisses();
  475. }
  476. SetLastError(dwError);
  477. return FALSE;
  478. }
  479. BOOL
  480. CheckoutFileEntry(
  481. IN TS_OPEN_FILE_INFO * pOpenFile,
  482. IN DWORD dwFlags
  483. )
  484. /*++
  485. Routine Description:
  486. This function checks out an entry to which the caller already has
  487. a reference.
  488. The FCF_FOR_IO flag indicates that the caller will be performing
  489. I/O operations with the cached file handle.
  490. Arguments:
  491. pOpenFile - The file info structure to be checked out.
  492. dwFlags - The only valid flag is FCF_FOR_IO.
  493. Return Value:
  494. TRUE - File was successfully checked out
  495. FALSE - File was checked out, but should not be used by the
  496. caller. (it's been flushed)
  497. --*/
  498. {
  499. BOOL bSuccess;
  500. CHECK_FILE_STATE( pOpenFile );
  501. pOpenFile->AddRef();
  502. pOpenFile->Lock();
  503. if (dwFlags & FCF_FOR_IO) {
  504. I_AddRefIO(pOpenFile);
  505. }
  506. if (pOpenFile->IsFlushed() == FALSE) {
  507. bSuccess = TRUE;
  508. } else {
  509. bSuccess = FALSE;
  510. }
  511. if (dwFlags & FCF_FOR_IO) {
  512. if (bSuccess) {
  513. g_pFileCacheStats->IncHits();
  514. } else {
  515. g_pFileCacheStats->IncMisses();
  516. }
  517. }
  518. pOpenFile->Unlock();
  519. return bSuccess;
  520. }
  521. VOID
  522. CheckinFile(
  523. IN TS_OPEN_FILE_INFO * pOpenFile,
  524. IN DWORD dwFlags
  525. )
  526. /*++
  527. Routine Description:
  528. Indicate that a previously checked out file info is no longer in use.
  529. The FCF_FOR_IO flag indicates that the caller was be performing I/O
  530. operations with the cached file handle. This flag will be clear in
  531. most cases except in TsCloseHandle.
  532. Arguments:
  533. pOpenFile - The file info structure to be checked in.
  534. dwFlags - The only valid flag is FCF_FOR_IO.
  535. Return Value:
  536. None.
  537. --*/
  538. {
  539. BOOL bShouldClose;
  540. CHECK_FILE_STATE( pOpenFile );
  541. //
  542. // update state
  543. //
  544. pOpenFile->Lock();
  545. if (dwFlags & FCF_FOR_IO) {
  546. I_DerefIO(pOpenFile);
  547. }
  548. bShouldClose = pOpenFile->IsCloseable();
  549. pOpenFile->Unlock();
  550. //
  551. // Clean up as necessary
  552. //
  553. if (bShouldClose) {
  554. pOpenFile->CloseHandle();
  555. }
  556. I_DerefFileInfo(pOpenFile);
  557. }
  558. inline VOID
  559. I_DerefFileInfo(
  560. TS_OPEN_FILE_INFO *pOpenFile
  561. )
  562. /*++
  563. --*/
  564. {
  565. LONG lRefCount;
  566. DBG_ASSERT( pOpenFile != NULL );
  567. DBG_ASSERT( pOpenFile->CheckSignature() );
  568. lRefCount = pOpenFile->Deref();
  569. DBG_ASSERT( lRefCount >= 0 );
  570. if (lRefCount == 0) {
  571. DBG_ASSERT(pOpenFile->IsFlushed());
  572. delete pOpenFile;
  573. g_pFileCacheStats->DecFlushedEntries();
  574. }
  575. }
  576. VOID
  577. I_AddRefIO(
  578. TS_OPEN_FILE_INFO * pOpenFile
  579. )
  580. /*++
  581. Routine Description:
  582. Calls pOpenFile->AddRefIO.
  583. This should be called with the fileinfo lock held.
  584. Arguments:
  585. pOpenFile - the file to addref
  586. Return Value:
  587. None.
  588. --*/
  589. {
  590. pOpenFile->AddRefIO();
  591. }
  592. VOID
  593. I_DerefIO(
  594. TS_OPEN_FILE_INFO * pOpenFile
  595. )
  596. /*++
  597. Routine Description:
  598. Calls pOpenFile->DerefIO.
  599. This should be called with the fileinfo lock held.
  600. Arguments:
  601. pOpenFile - the file to deref
  602. Return Value:
  603. None.
  604. --*/
  605. {
  606. pOpenFile->DerefIO();
  607. }
  608. VOID
  609. TS_OPEN_FILE_INFO::Print(
  610. VOID
  611. ) const
  612. {
  613. //
  614. // Doesn't do anything. Ha!
  615. //
  616. }
  617. BOOL
  618. CFileCacheStats::DumpToHtml(
  619. CHAR * pchBuffer,
  620. LPDWORD lpcbBuffer) const
  621. {
  622. *lpcbBuffer = wsprintf(pchBuffer,
  623. "<table>"
  624. "<tr><td>Currently Cached Files</td><td align=right>%d</td></tr>"
  625. "<tr><td>Total # of files added</td><td align=right>%d</td></tr>"
  626. "<tr><td>Cache Hits</td><td align=right>%d</td></tr>"
  627. "<tr><td>Cache Misses</td><td align=right>%d</td></tr>"
  628. "<tr><td>Cache Flushes</td><td align=right>%d</td></tr>"
  629. "<tr><td>Oplock Breaks</td><td align=right>%d</td></tr>"
  630. "<tr><td>Oplock Breaks To None</td><td align=right>%d</td></tr>"
  631. "<tr><td>Flushed entries in cache</td><td align=right>%d</td></tr>"
  632. "<tr><td>Total # files flushed</td><td align=right>%d</td></tr>"
  633. "</table>",
  634. FilesCached,
  635. TotalFilesCached,
  636. Hits,
  637. Misses,
  638. Flushes,
  639. OplockBreaks,
  640. OplockBreaksToNone,
  641. FlushedEntries,
  642. TotalFlushed );
  643. return TRUE;
  644. }
  645. BOOL
  646. CFileCacheStats::QueryStats(
  647. INETA_CACHE_STATISTICS * pCacheCtrs
  648. ) const
  649. {
  650. return FALSE;
  651. }
  652. BOOL
  653. FileFlushFilterAll(
  654. TS_OPEN_FILE_INFO *pOpenFile,
  655. PVOID pv
  656. )
  657. {
  658. return TRUE;
  659. }
  660. #if DBG
  661. BOOL
  662. CheckFileState(
  663. TS_OPEN_FILE_INFO *pOpenFile
  664. )
  665. {
  666. DBG_ASSERT( pOpenFile );
  667. DBG_ASSERT( pOpenFile->CheckSignature() );
  668. DBG_ASSERT( pOpenFile->IsCached() );
  669. DBG_ASSERT( g_pFileInfoTable );
  670. TS_OPEN_FILE_INFO * pHashFile;
  671. BOOL bOK;
  672. //
  673. // I was going to do some interesting checks here
  674. // but the synchronization is just too hard
  675. //
  676. bOK = TRUE;
  677. return bOK;
  678. }
  679. #endif // DBG
  680. //
  681. // filecach.cxx
  682. //