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.

810 lines
24 KiB

  1. //+------------------------------------------------------------------
  2. //
  3. // Copyright (C) 1991-1997 Microsoft Corporation.
  4. //
  5. // File: idxnotif.cxx
  6. //
  7. // Contents: Document notification interfaces
  8. //
  9. // Classes: CIndexNotificationTable
  10. //
  11. // History: 24-Feb-97 SitaramR Created
  12. //
  13. //-------------------------------------------------------------------
  14. #include <pch.cxx>
  15. #pragma hdrstop
  16. #include "idxnotif.hxx"
  17. #include "idxentry.hxx"
  18. #include "notifdoc.hxx"
  19. #include "cimanger.hxx"
  20. //+---------------------------------------------------------------------------
  21. //
  22. // Member: CIndexNotificationTable::CIndexNotificationTable
  23. //
  24. // Synopsis: Constructor
  25. //
  26. // History: 24-Feb-97 SitaramR Created
  27. //
  28. //----------------------------------------------------------------------------
  29. CIndexNotificationTable::CIndexNotificationTable( CCiManager * pCiManager,
  30. XInterface<ICiCDocStore> & xDocStore )
  31. : _pCiManager( pCiManager ),
  32. _xDocStore( xDocStore.Acquire() ),
  33. _fInitialized( FALSE ),
  34. _fShutdown( FALSE ),
  35. _usnCtr( 1 ),
  36. _cRefs( 1 )
  37. {
  38. for ( ULONG i=0; i<NOTIF_HASH_TABLE_SIZE; i++)
  39. _aHashTable[i] = 0;
  40. }
  41. //+---------------------------------------------------------------------------
  42. //
  43. // Member: CIndexNotificationTable::~CIndexNotificationTable
  44. //
  45. // Synopsis: Destructor
  46. //
  47. // History: 24-Feb-97 SitaramR Created
  48. //
  49. //----------------------------------------------------------------------------
  50. CIndexNotificationTable::~CIndexNotificationTable()
  51. {
  52. Shutdown();
  53. }
  54. //+-------------------------------------------------------------------------
  55. //
  56. // Method: CIndexNotificationTable::AddRef
  57. //
  58. // Synopsis: Increments refcount
  59. //
  60. // History: 24-Feb-1997 SitaramR Created
  61. //
  62. //--------------------------------------------------------------------------
  63. ULONG STDMETHODCALLTYPE CIndexNotificationTable::AddRef()
  64. {
  65. return InterlockedIncrement( (long *) &_cRefs );
  66. }
  67. //+-------------------------------------------------------------------------
  68. //
  69. // Method: CIndexNotificationTable::Release
  70. //
  71. // Synopsis: Decrement refcount. Delete if necessary.
  72. //
  73. // History: 24-Feb-1997 SitaramR Created
  74. //
  75. //--------------------------------------------------------------------------
  76. ULONG STDMETHODCALLTYPE CIndexNotificationTable::Release()
  77. {
  78. Win4Assert( _cRefs > 0 );
  79. ULONG uTmp = InterlockedDecrement( (long *) &_cRefs );
  80. if ( 0 == uTmp )
  81. delete this;
  82. return uTmp;
  83. }
  84. //+-------------------------------------------------------------------------
  85. //
  86. // Method: CIndexNotificationTable::QueryInterface
  87. //
  88. // Synopsis: Rebind to other interface
  89. //
  90. // Arguments: [riid] -- IID of new interface
  91. // [ppvObject] -- New interface * returned here
  92. //
  93. // Returns: S_OK if bind succeeded, E_NOINTERFACE if bind failed
  94. //
  95. // History: 24-Feb-1997 SitaramR Created
  96. //
  97. //--------------------------------------------------------------------------
  98. SCODE STDMETHODCALLTYPE CIndexNotificationTable::QueryInterface( REFIID riid,
  99. void ** ppvObject)
  100. {
  101. Win4Assert( 0 != ppvObject );
  102. if ( riid == IID_ICiIndexNotification )
  103. *ppvObject = (void *)(ICiIndexNotification *) this;
  104. else if ( riid == IID_ICiCFilterClient )
  105. *ppvObject = (void *)(ICiCFilterClient *) this;
  106. else if ( riid == IID_ICiCAdviseStatus )
  107. return _xDocStore->QueryInterface( riid, ppvObject );
  108. else if ( riid == IID_ICiCLangRes )
  109. return _xDocStore->QueryInterface( riid, ppvObject );
  110. else if ( riid == IID_IUnknown )
  111. *ppvObject = (void *)(IUnknown *)(ICiIndexNotification *) this;
  112. else
  113. {
  114. *ppvObject = 0;
  115. return E_NOINTERFACE;
  116. }
  117. AddRef();
  118. return S_OK;
  119. }
  120. //+-------------------------------------------------------------------------
  121. //
  122. // Method: CIndexNotificationTable::AddNotification
  123. //
  124. // Synopsis: New document notification
  125. //
  126. // Arguments: [wid] -- Workid of document
  127. // [pIndexNotifStatus] -- Status of notifcation returned here
  128. // [ppIndexNotifEntry] -- Buffer to document properties
  129. //
  130. // History: 24-Feb-1997 SitaramR Created
  131. //
  132. //--------------------------------------------------------------------------
  133. SCODE STDMETHODCALLTYPE CIndexNotificationTable::AddNotification(
  134. WORKID wid,
  135. ICiCIndexNotificationStatus *pIndexNotifStatus,
  136. ICiIndexNotificationEntry **ppIndexNotifEntry )
  137. {
  138. Win4Assert( wid != widInvalid );
  139. Win4Assert( pIndexNotifStatus != 0 );
  140. if ( _fShutdown )
  141. return CI_E_SHUTDOWN;
  142. SCODE sc = S_OK;
  143. TRY
  144. {
  145. pIndexNotifStatus->AddRef();
  146. XInterface<ICiCIndexNotificationStatus> xNotifStatus( pIndexNotifStatus );
  147. CIndexNotificationEntry *pIndexNotifEntry;
  148. BOOL fFound;
  149. {
  150. CLock lock(_mutex);
  151. fFound = LokLookup( wid, pIndexNotifEntry );
  152. if ( fFound )
  153. sc = CI_E_DUPLICATE_NOTIFICATION;
  154. }
  155. if ( !fFound )
  156. {
  157. AddRef();
  158. XInterface<CIndexNotificationTable> xNotifTable(this);
  159. CheckForUsnOverflow();
  160. USN usn = InterlockedIncrement( &_usnCtr );
  161. pIndexNotifEntry = new CIndexNotificationEntry( wid,
  162. CI_UPDATE_ADD,
  163. xNotifTable,
  164. xNotifStatus,
  165. _pCiManager,
  166. usn );
  167. XInterface<CIndexNotificationEntry> xIndexNotifEntry( pIndexNotifEntry );
  168. CHashTableEntry *pHashEntry = new CHashTableEntry( wid, pIndexNotifEntry );
  169. {
  170. CLock lock(_mutex);
  171. LokNoFailAdd( pHashEntry );
  172. if ( _fShutdown )
  173. pIndexNotifEntry->Shutdown();
  174. }
  175. xIndexNotifEntry.Acquire(); // Passed ownership to hash table
  176. sc = pIndexNotifEntry->QueryInterface( IID_ICiIndexNotificationEntry,
  177. (void **)ppIndexNotifEntry );
  178. //
  179. // No release on pIndexNotifEntry because both the hash table the client
  180. // own pIndexNotifEntry
  181. //
  182. Win4Assert( SUCCEEDED( sc ) );
  183. }
  184. }
  185. CATCH( CException, e )
  186. {
  187. sc = e.GetErrorCode();
  188. ciDebugOut(( DEB_ERROR,
  189. "CIndexNotificationTable::AddNotification - Exception caught 0x%x\n",
  190. sc ));
  191. }
  192. END_CATCH;
  193. return sc;
  194. }
  195. //+-------------------------------------------------------------------------
  196. //
  197. // Method: CIndexNotificationTable::ModifyNotification
  198. //
  199. // Synopsis: Change document notification
  200. //
  201. // Arguments: [wid] -- Workid of document
  202. // [pIndexNotifStatus] -- Status of notifcation returned here
  203. // [ppIndexNotifEntry] -- Buffer to document properties
  204. //
  205. // History: 24-Feb-1997 SitaramR Created
  206. //
  207. //--------------------------------------------------------------------------
  208. SCODE STDMETHODCALLTYPE CIndexNotificationTable::ModifyNotification(
  209. WORKID wid,
  210. ICiCIndexNotificationStatus *pIndexNotifStatus,
  211. ICiIndexNotificationEntry **ppIndexNotifEntry )
  212. {
  213. //
  214. // There is no difference between an add and a modify in the CI engine
  215. //
  216. SCODE sc = AddNotification( wid, pIndexNotifStatus, ppIndexNotifEntry );
  217. return sc;
  218. }
  219. //+-------------------------------------------------------------------------
  220. //
  221. // Method: CIndexNotificationTable::DeleteNotification
  222. //
  223. // Synopsis: Delete document notification
  224. //
  225. // Arguments: [wid] -- Workid of document
  226. // [pIndexNotifStatus] -- Status of notifcation returned here
  227. //
  228. // History: 24-Feb-1997 SitaramR Created
  229. //
  230. //--------------------------------------------------------------------------
  231. SCODE STDMETHODCALLTYPE CIndexNotificationTable::DeleteNotification(
  232. WORKID wid,
  233. ICiCIndexNotificationStatus *pIndexNotifStatus )
  234. {
  235. Win4Assert( wid != widInvalid );
  236. Win4Assert( pIndexNotifStatus != 0 );
  237. if ( _fShutdown )
  238. return CI_E_SHUTDOWN;
  239. SCODE sc = S_OK;
  240. TRY
  241. {
  242. pIndexNotifStatus->AddRef();
  243. XInterface<ICiCIndexNotificationStatus> xNotifStatus( pIndexNotifStatus );
  244. CIndexNotificationEntry *pIndexNotifEntry;
  245. BOOL fFound;
  246. {
  247. CLock lock(_mutex);
  248. fFound = LokLookup( wid, pIndexNotifEntry );
  249. if ( fFound )
  250. sc = CI_E_DUPLICATE_NOTIFICATION;
  251. }
  252. if ( !fFound )
  253. {
  254. CheckForUsnOverflow();
  255. USN usn = InterlockedIncrement( &_usnCtr );
  256. AddRef();
  257. XInterface<CIndexNotificationTable> xNotifTable(this);
  258. pIndexNotifEntry = new CIndexNotificationEntry( wid,
  259. CI_UPDATE_DELETE,
  260. xNotifTable,
  261. xNotifStatus,
  262. _pCiManager,
  263. usn );
  264. XInterface<CIndexNotificationEntry> xIndexNotifEntry( pIndexNotifEntry );
  265. CHashTableEntry *pHashEntry = new CHashTableEntry( wid, pIndexNotifEntry );
  266. XPtr<CHashTableEntry> xHashEntry( pHashEntry );
  267. CDocumentUpdateInfo info( wid, CI_VOLID_USN_NOT_ENABLED, usn, TRUE );
  268. sc = _pCiManager->UpdDocumentNoThrow( &info );
  269. if ( FAILED( sc ) )
  270. {
  271. SCODE scode = pIndexNotifStatus->Abort();
  272. //
  273. // We don't have retry logic coded in case of failure,
  274. // hence check that it succeeded
  275. //
  276. Win4Assert( SUCCEEDED( scode ) );
  277. }
  278. else
  279. {
  280. CLock lock(_mutex);
  281. LokNoFailAdd( pHashEntry );
  282. if ( _fShutdown )
  283. pIndexNotifEntry->Shutdown();
  284. xIndexNotifEntry.Acquire(); // Passed ownership to hash table
  285. xHashEntry.Acquire();
  286. }
  287. }
  288. }
  289. CATCH( CException, e )
  290. {
  291. sc = e.GetErrorCode();
  292. ciDebugOut(( DEB_ERROR,
  293. "CIndexNotificationTable::DeleteNotification - Exception caught 0x%x\n",
  294. sc ));
  295. }
  296. END_CATCH;
  297. return sc;
  298. }
  299. //+-------------------------------------------------------------------------
  300. //
  301. // Method: CIndexNotificationTable::GetConfigInfo
  302. //
  303. // Synopsis: Return configuration info
  304. //
  305. // Arguments: [pConfigInfo] - output data structure
  306. //
  307. // History: 24-Feb-1997 SitaramR Created
  308. //
  309. //--------------------------------------------------------------------------
  310. SCODE STDMETHODCALLTYPE CIndexNotificationTable::GetConfigInfo(
  311. CI_CLIENT_FILTER_CONFIG_INFO *pConfigInfo )
  312. {
  313. //
  314. // Security generation must be specified as part of configuration
  315. // information to the push model.
  316. //
  317. pConfigInfo->fSupportsOpLocks = FALSE;
  318. pConfigInfo->fSupportsSecurity = FALSE;
  319. return S_OK;
  320. }
  321. //+---------------------------------------------------------------------------
  322. //
  323. // Member: CIndexNotificationTable::Init
  324. //
  325. // Synopsis: Initialize storage filtering
  326. //
  327. // Arguments: [pbData] - input data, ignored
  328. // [cbData] - length of data, ignored
  329. // [pICiAdminParams] - interface for retrieving configuration
  330. //
  331. // History: 24-Feb-1997 SitaramR Created
  332. //
  333. //----------------------------------------------------------------------------
  334. SCODE STDMETHODCALLTYPE CIndexNotificationTable::Init( const BYTE * pbData,
  335. ULONG cbData,
  336. ICiAdminParams *pICiAdminParams )
  337. {
  338. _fInitialized = TRUE;
  339. return S_OK;
  340. }
  341. //+---------------------------------------------------------------------------
  342. //
  343. // Member: CIndexNotificationTable::GetOpenedDoc
  344. //
  345. // Synopsis: Return a new OpenedDoc instance
  346. //
  347. // Arguments: [ppICiCOpenedDoc] - Interface pointer returned here
  348. //
  349. // History: 24-Feb-1997 SitaramR Created
  350. //
  351. //----------------------------------------------------------------------------
  352. SCODE STDMETHODCALLTYPE CIndexNotificationTable::GetOpenedDoc( ICiCOpenedDoc ** ppICiCOpenedDoc )
  353. {
  354. if ( !_fInitialized )
  355. {
  356. ppICiCOpenedDoc = 0;
  357. return CI_E_NOT_INITIALIZED;
  358. }
  359. SCODE sc = S_OK;
  360. TRY
  361. {
  362. AddRef();
  363. XInterface<CIndexNotificationTable> xNotifTable( this );
  364. CINOpenedDoc *pOpenedDoc = new CINOpenedDoc( xNotifTable );
  365. sc = pOpenedDoc->QueryInterface( IID_ICiCOpenedDoc, (void **)ppICiCOpenedDoc );
  366. pOpenedDoc->Release(); // QI does an AddRef
  367. }
  368. CATCH( CException, e )
  369. {
  370. sc = e.GetErrorCode();
  371. ciDebugOut(( DEB_ERROR,
  372. "CIndexNotificationTable::GetOpenedDoc - Exception caught 0x%x\n",
  373. sc ));
  374. }
  375. END_CATCH;
  376. return sc;
  377. }
  378. //+---------------------------------------------------------------------------
  379. //
  380. // Member: CIndexNotificationTable::Hash
  381. //
  382. // Synopsis: Implements the hash function
  383. //
  384. // Arguments: [wid] - Workid to hash
  385. //
  386. // History: 24-Feb-1997 SitaramR Created
  387. //
  388. // Returns: Position of chained list in hash table
  389. //
  390. //----------------------------------------------------------------------------
  391. ULONG CIndexNotificationTable::Hash( WORKID wid )
  392. {
  393. return wid % NOTIF_HASH_TABLE_SIZE;
  394. }
  395. //+---------------------------------------------------------------------------
  396. //
  397. // Member: CIndexNotificationTable::LokLookup
  398. //
  399. // Synopsis: Return the mapping corresponding to given wid
  400. //
  401. // Arguments: [wid] -- Workid to hash
  402. // [pIndexNotifEntry] -- Index entry returned here
  403. //
  404. // History: 24-Feb-1997 SitaramR Created
  405. //
  406. // Returns: True if a mapping was found in the hash table
  407. //
  408. //----------------------------------------------------------------------------
  409. BOOL CIndexNotificationTable::LokLookup( WORKID wid,
  410. CIndexNotificationEntry * &pIndexNotifEntry )
  411. {
  412. unsigned uHashValue = Hash( wid );
  413. Win4Assert( uHashValue < NOTIF_HASH_TABLE_SIZE );
  414. for ( CHashTableEntry *pHashEntry = _aHashTable[uHashValue];
  415. pHashEntry != 0;
  416. pHashEntry = pHashEntry->GetNextHashEntry() )
  417. {
  418. if ( pHashEntry->GetWorkId() == wid )
  419. {
  420. pIndexNotifEntry = pHashEntry->GetNotifEntry();
  421. return TRUE;
  422. }
  423. }
  424. return FALSE;
  425. }
  426. //+---------------------------------------------------------------------------
  427. //
  428. // Member: CIndexNotificationTable::LokNoFailAdd
  429. //
  430. // Synopsis: Add a wid->pIndexEntry mapping
  431. //
  432. // Arguments: [pHashEntry] -- Hash entry
  433. //
  434. // History: 24-Feb-1997 SitaramR Created
  435. //
  436. // Notes: LokNoFailAdd should not fail due to memory allocations
  437. //
  438. //----------------------------------------------------------------------------
  439. void CIndexNotificationTable::LokNoFailAdd( CHashTableEntry *pHashEntry )
  440. {
  441. #if DBG == 1
  442. //
  443. // Check for duplicate entries
  444. //
  445. CIndexNotificationEntry *pExistingData;
  446. BOOL fFound = LokLookup( pHashEntry->GetWorkId(), pExistingData );
  447. Win4Assert( !fFound );
  448. #endif
  449. unsigned uHashValue = Hash( pHashEntry->GetWorkId() );
  450. pHashEntry->SetNextHashEntry( _aHashTable[uHashValue] );
  451. _aHashTable[uHashValue] = pHashEntry;
  452. ciDebugOut(( DEB_ITRACE, "Adding Workid %d at %d hash entry\n",
  453. pHashEntry->GetWorkId(),
  454. uHashValue ));
  455. }
  456. //+---------------------------------------------------------------------------
  457. //
  458. // Member: CIndexNotificationTable::LokRemove
  459. //
  460. // Synopsis: Return the mapping corresponding to given wid
  461. //
  462. // Arguments: [wid] -- Workid to hash
  463. // [xIndexNotifEntry] -- Index entry returned here
  464. //
  465. // History: 24-Feb-1997 SitaramR Created
  466. //
  467. //----------------------------------------------------------------------------
  468. void CIndexNotificationTable::LokRemove( WORKID wid,
  469. XInterface<CIndexNotificationEntry> & xIndexNotifEntry )
  470. {
  471. unsigned uHashValue = Hash( wid );
  472. Win4Assert( uHashValue < NOTIF_HASH_TABLE_SIZE );
  473. CHashTableEntry *pHashEntry = _aHashTable[uHashValue];
  474. if ( pHashEntry == 0 )
  475. {
  476. Win4Assert( !"Wid not found in hash table" );
  477. return;
  478. }
  479. if ( pHashEntry->GetWorkId() == wid )
  480. {
  481. //
  482. // Wid is the first entry in chain
  483. //
  484. _aHashTable[uHashValue] = pHashEntry->GetNextHashEntry();
  485. xIndexNotifEntry.Set( pHashEntry->GetNotifEntry() );
  486. ciDebugOut(( DEB_ITRACE, "Removing Workid %d:%d at %d hash entry\n",
  487. pHashEntry->GetWorkId(), wid,
  488. uHashValue ));
  489. delete pHashEntry;
  490. return;
  491. }
  492. CHashTableEntry *pHashEntryPrev = pHashEntry;
  493. pHashEntry = pHashEntry->GetNextHashEntry();
  494. while ( pHashEntry != 0 )
  495. {
  496. if ( pHashEntry->GetWorkId() == wid )
  497. {
  498. pHashEntryPrev->SetNextHashEntry( pHashEntry->GetNextHashEntry() );
  499. xIndexNotifEntry.Set( pHashEntry->GetNotifEntry() );
  500. ciDebugOut(( DEB_ITRACE, "Removing Workid %d:%d at %d hash entry\n",
  501. pHashEntry->GetWorkId(), wid,
  502. uHashValue ));
  503. delete pHashEntry;
  504. return;
  505. }
  506. pHashEntryPrev = pHashEntry;
  507. pHashEntry = pHashEntry->GetNextHashEntry();
  508. }
  509. Win4Assert( !"Wid not found in hash table" );
  510. }
  511. //+---------------------------------------------------------------------------
  512. //
  513. // Member: CIndexNotificationTable::Remove
  514. //
  515. // Synopsis: Return the mapping corresponding to given wid
  516. //
  517. // Arguments: [wid] -- Workid to hash
  518. // [xIndexNotifEntry] -- Index entry returned here
  519. //
  520. // History: 24-Feb-1997 SitaramR Created
  521. //
  522. //----------------------------------------------------------------------------
  523. void CIndexNotificationTable::Remove( WORKID wid,
  524. XInterface<CIndexNotificationEntry> & xIndexNotifEntry )
  525. {
  526. CLock lock(_mutex);
  527. LokRemove( wid, xIndexNotifEntry );
  528. }
  529. //+---------------------------------------------------------------------------
  530. //
  531. // Member: CIndexNotificationTable::Lookup
  532. //
  533. // Synopsis: Lookup the mapping corresponding to given wid
  534. //
  535. // Arguments: [wid] -- Workid to hash
  536. // [pIndexNotifEntry] -- Index entry returned here
  537. //
  538. // History: 24-Feb-1997 SitaramR Created
  539. //
  540. //----------------------------------------------------------------------------
  541. BOOL CIndexNotificationTable::Lookup( WORKID wid,
  542. CIndexNotificationEntry * &pIndexNotifEntry )
  543. {
  544. CLock lock(_mutex);
  545. return LokLookup( wid, pIndexNotifEntry );
  546. }
  547. //+---------------------------------------------------------------------------
  548. //
  549. // Member: CIndexNotificationTable::CommitWids
  550. //
  551. // Synopsis: Commits the notification status transactions on the given list
  552. // of wids
  553. //
  554. // Arguments: [aWidsInPersIndex] -- Array of wids to be committed
  555. //
  556. // History: 24-Feb-1997 SitaramR Created
  557. //
  558. //----------------------------------------------------------------------------
  559. void CIndexNotificationTable::CommitWids( CDynArrayInPlace<WORKID> & aWidsInPersIndex )
  560. {
  561. for ( ULONG i=0; i<aWidsInPersIndex.Count(); i++)
  562. {
  563. WORKID wid = aWidsInPersIndex.Get( i );
  564. XInterface<CIndexNotificationEntry> xIndexNotifEntry;
  565. {
  566. CLock lock(_mutex);
  567. LokRemove( wid, xIndexNotifEntry );
  568. }
  569. Win4Assert( !xIndexNotifEntry.IsNull() );
  570. xIndexNotifEntry->Commit(); // Commit client transaction
  571. //
  572. // xIndexNotifEntry is released when it goes out of scope
  573. //
  574. }
  575. }
  576. //+---------------------------------------------------------------------------
  577. //
  578. // Member: CIndexNotificationTable::AbortWid
  579. //
  580. // Synopsis: Commits the notification status transactions on the given list
  581. // of wids
  582. //
  583. // Arguments: [cWidsInPersIndex] -- Count of wids in array
  584. // [aWidsInPersIndex] -- Array of wids to be committed
  585. //
  586. // History: 24-Feb-1997 SitaramR Created
  587. //
  588. //----------------------------------------------------------------------------
  589. void CIndexNotificationTable::AbortWid( WORKID wid, USN usn )
  590. {
  591. XInterface<CIndexNotificationEntry> xIndexNotifEntry;
  592. {
  593. CLock lock(_mutex);
  594. LokRemove( wid, xIndexNotifEntry );
  595. }
  596. Win4Assert( !xIndexNotifEntry.IsNull() );
  597. Win4Assert( xIndexNotifEntry->Usn() == usn );
  598. xIndexNotifEntry->Abort(); // Abort client transaction
  599. //
  600. // xIndexNotifEntry is released when it goes out of scope
  601. //
  602. }
  603. //+---------------------------------------------------------------------------
  604. //
  605. // Member: CIndexNotificationTable::CheckForUsnOverflow
  606. //
  607. // Synopsis: Handles overflows of usn by resetting the counter to 1
  608. //
  609. // History: 24-Feb-1997 SitaramR Created
  610. //
  611. //----------------------------------------------------------------------------
  612. void CIndexNotificationTable::CheckForUsnOverflow()
  613. {
  614. if ( _usnCtr == LONG_MAX )
  615. {
  616. //
  617. // Overflow should be rare, if ever
  618. //
  619. Win4Assert( !"Usn counter overflow, resetting" );
  620. InterlockedExchange( &_usnCtr, 1 );
  621. }
  622. }
  623. //+---------------------------------------------------------------------------
  624. //
  625. // Member: CIndexNotificationTable::Shutdown
  626. //
  627. // Synopsis: Shutdown processing
  628. //
  629. // History: 24-Feb-97 SitaramR Created
  630. //
  631. //----------------------------------------------------------------------------
  632. void CIndexNotificationTable::Shutdown()
  633. {
  634. //
  635. // Shutdown all entries in hash table
  636. //
  637. CLock lock( _mutex );
  638. _fShutdown = TRUE;
  639. for ( ULONG i=0; i<NOTIF_HASH_TABLE_SIZE; i++ )
  640. {
  641. CHashTableEntry *pEntry = _aHashTable[i];
  642. _aHashTable[i] = 0;
  643. while ( pEntry != 0 )
  644. {
  645. CHashTableEntry *pEntryPrev = pEntry;
  646. pEntry = pEntry->GetNextHashEntry();
  647. CIndexNotificationEntry *pIndexNotifEntry = pEntryPrev->GetNotifEntry();
  648. pIndexNotifEntry->Shutdown();
  649. pIndexNotifEntry->Release();
  650. delete pEntryPrev;
  651. }
  652. }
  653. }