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.

636 lines
18 KiB

  1. //+---------------------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1996-1998.
  5. //
  6. // File: PropObj.hxx
  7. //
  8. // Contents: Encapsulates long-term access to single record of property
  9. // store.
  10. //
  11. // Classes: CLockRecordForRead
  12. //
  13. // History: 27-Dec-19 KyleP Created
  14. //
  15. //----------------------------------------------------------------------------
  16. #pragma once
  17. #include <proprec.hxx>
  18. #include <prpstmgr.hxx>
  19. #include <borrow.hxx>
  20. //+-------------------------------------------------------------------------
  21. //
  22. // Class: CLockRecordForRead
  23. //
  24. // Purpose: Smart encapsulation of read-lock
  25. //
  26. // History: 19-Dec-95 KyleP Created
  27. //
  28. //--------------------------------------------------------------------------
  29. class CLockRecordForRead
  30. {
  31. public:
  32. CLockRecordForRead( CPropertyStore & store, WORKID wid )
  33. : _store( store ),
  34. _record ( store.LockMgr().GetRecord( wid ) )
  35. {
  36. _store.AcquireRead( _record );
  37. }
  38. ~CLockRecordForRead()
  39. {
  40. _store.ReleaseRead( _record );
  41. }
  42. private:
  43. CReadWriteLockRecord & _record;
  44. CPropertyStore & _store;
  45. };
  46. //+-------------------------------------------------------------------------
  47. //
  48. // Class: CLockRecordForWrite
  49. //
  50. // Purpose: Smart encapsulation of write-lock
  51. //
  52. // History: 19-Dec-95 KyleP Created
  53. //
  54. //--------------------------------------------------------------------------
  55. class CLockRecordForWrite
  56. {
  57. public:
  58. CLockRecordForWrite( CPropertyStore & store, WORKID wid )
  59. : _store( store ),
  60. _record ( store.LockMgr().GetRecord( wid ) )
  61. {
  62. _store.AcquireWrite( _record );
  63. }
  64. ~CLockRecordForWrite()
  65. {
  66. _store.ReleaseWrite( _record );
  67. }
  68. private:
  69. CReadWriteLockRecord & _record;
  70. CPropertyStore & _store;
  71. };
  72. //+-------------------------------------------------------------------------
  73. //
  74. // Class: CLockAllRecordsForWrite
  75. //
  76. // Purpose: Smart encapsulation of total reader lock out.
  77. //
  78. // History: 18-Nov-97 KrishnaN Created
  79. //
  80. //--------------------------------------------------------------------------
  81. class CLockAllRecordsForWrite
  82. {
  83. public:
  84. CLockAllRecordsForWrite( CPropertyStore & store)
  85. : _store( store )
  86. {
  87. _store.AcquireWriteOnAllRecords();
  88. }
  89. ~CLockAllRecordsForWrite()
  90. {
  91. _store.ReleaseWriteOnAllRecords();
  92. }
  93. private:
  94. CPropertyStore & _store;
  95. };
  96. //+-------------------------------------------------------------------------
  97. //
  98. // Class: CPropRecordNoLock
  99. //
  100. // Purpose: Encapsulates long-term access to single record of
  101. // property store.
  102. //
  103. // History: 18-Mar-98 KrishnaN Created
  104. //
  105. //--------------------------------------------------------------------------
  106. class CPropRecordNoLock
  107. {
  108. public:
  109. inline CPropRecordNoLock( WORKID wid,
  110. CPropertyStore & store,
  111. BOOL fIntentToWrite );
  112. inline void * operator new( size_t size, BYTE * pb );
  113. inline void operator delete( void * p );
  114. #if _MSC_VER >= 1200
  115. inline void operator delete( void * p, BYTE * pb );
  116. #endif
  117. inline BOOL IsValid() { return 0 != _wid; }
  118. protected:
  119. friend class CPropertyStore;
  120. // _wid should be the first to be declared. The constructor depends
  121. // on that!
  122. WORKID _wid;
  123. COnDiskPropertyRecord * _prec;
  124. CBorrowed _Borrowed;
  125. };
  126. //+-------------------------------------------------------------------------
  127. //
  128. // Member: CPropRecordNoLock::CPropRecordNoLock, public
  129. //
  130. // Synopsis: Takes all locks required to hold record open until
  131. // destruction.
  132. //
  133. // Arguments: [wid] -- Workid of record to open.
  134. // [store] -- Property store.
  135. //
  136. // History: 18-Mar-98 KrishnaN Created
  137. //
  138. //--------------------------------------------------------------------------
  139. inline CPropRecordNoLock::CPropRecordNoLock(
  140. WORKID wid,
  141. CPropertyStore & store,
  142. BOOL fIntentToWrite )
  143. : _wid ( (wid > store.MaxWorkId()) ? 0 : wid),
  144. _Borrowed( store._xPhysStore.GetReference(),
  145. _wid,
  146. store._PropStoreInfo.RecordsPerPage(),
  147. store._PropStoreInfo.RecordSize(),
  148. fIntentToWrite )
  149. {
  150. //
  151. // The next line can't be in ':' initialization because
  152. // 1) _prec is first in structure to avoid C++ EH macro problems
  153. // 2) If _prec is in ':' section it is initialized before _Borrowed!
  154. //
  155. _prec = _Borrowed.Get();
  156. }
  157. //+-------------------------------------------------------------------------
  158. //
  159. // Member: CPropRecordNoLock::operator new, public
  160. //
  161. // Synopsis: Special operator new
  162. //
  163. // Arguments: [size] -- Size of allocation
  164. // [pb] -- Pre-allocated memory
  165. //
  166. // History: 18-Mar-98 KrishnaN Created
  167. //
  168. //--------------------------------------------------------------------------
  169. void * CPropRecordNoLock::operator new( size_t size, BYTE * pb )
  170. {
  171. Win4Assert( 0 == ( ((ULONG_PTR)pb) & 0x3 ) );
  172. if( 0 == pb )
  173. THROW( CException( E_OUTOFMEMORY ) );
  174. return pb;
  175. }
  176. //+-------------------------------------------------------------------------
  177. //
  178. // Member: CPropRecordNoLock::operator delete, public
  179. //
  180. // Synopsis: Special operator delete
  181. //
  182. // Arguments: [p] -- Pointer to "delete"
  183. //
  184. // History: 03-Apr-96 KyleP Created
  185. //
  186. //--------------------------------------------------------------------------
  187. void CPropRecordNoLock::operator delete( void * p )
  188. {
  189. }
  190. #if _MSC_VER >= 1200
  191. void CPropRecordNoLock::operator delete(void * p, BYTE * pb) {}
  192. #endif
  193. //+-------------------------------------------------------------------------
  194. //
  195. // Class: CPropRecord
  196. //
  197. // Purpose: Encapsulates long-term read access to single record of
  198. // property store.
  199. //
  200. // History: 27-Dec-95 KyleP Created
  201. //
  202. //--------------------------------------------------------------------------
  203. class CPropRecord : public CPropRecordNoLock
  204. {
  205. public:
  206. inline CPropRecord( WORKID wid, CPropertyStore & store );
  207. private:
  208. friend class CPropertyStore;
  209. // _wid should be the first to be declared. The constructor depends
  210. // on that!
  211. CLockRecordForRead _lock;
  212. };
  213. //+-------------------------------------------------------------------------
  214. //
  215. // Member: CPropRecord::CPropRecord, public
  216. //
  217. // Synopsis: Takes all locks required to hold record open until
  218. // destruction. The phystr buffer is opened for write with
  219. // intent to read.
  220. //
  221. // Arguments: [wid] -- Workid of record to open.
  222. // [store] -- Property store.
  223. //
  224. // History: 03-Apr-96 KyleP Created
  225. //
  226. //--------------------------------------------------------------------------
  227. inline CPropRecord::CPropRecord( WORKID wid, CPropertyStore & store )
  228. : CPropRecordNoLock(wid, store, FALSE),
  229. _lock( store, _wid )
  230. {
  231. }
  232. //+-------------------------------------------------------------------------
  233. //
  234. // Class: CPrimaryPropRecord
  235. //
  236. // Purpose: Encapsulates long-term access to a top-level record
  237. // of property store.
  238. //
  239. // History: 2-Jan-99 dlee Created
  240. //
  241. //--------------------------------------------------------------------------
  242. class CPrimaryPropRecord
  243. {
  244. public:
  245. CPrimaryPropRecord( WORKID wid, CPropStoreManager & store )
  246. : _PrimaryRecord( wid, store.GetPrimaryStore()) {}
  247. void * operator new( size_t size, BYTE * pb )
  248. {
  249. Win4Assert( 0 == ( ((ULONG_PTR)pb) & 0x7 ) );
  250. if( 0 == pb )
  251. THROW( CException( E_OUTOFMEMORY ) );
  252. return pb;
  253. }
  254. void operator delete( void * p ) {}
  255. #if _MSC_VER >= 1200
  256. void operator delete( void * p, BYTE * pb ) {}
  257. #endif
  258. CPropRecord & GetPrimaryPropRecord() { return _PrimaryRecord; }
  259. private:
  260. CPropRecord _PrimaryRecord;
  261. };
  262. //+-------------------------------------------------------------------------
  263. //
  264. // Class: CCompositePropRecord
  265. //
  266. // Purpose: Encapsulates long-term access to the two top-level records
  267. // of property store.
  268. //
  269. // History: 22-Oct-97 KrishnaN Created
  270. //
  271. //--------------------------------------------------------------------------
  272. class CCompositePropRecord
  273. {
  274. public:
  275. inline CCompositePropRecord( WORKID wid, CPropStoreManager & store );
  276. inline void * operator new( size_t size, BYTE * pb );
  277. inline void operator delete( void * p );
  278. #if _MSC_VER >= 1200
  279. inline void operator delete( void * p, BYTE * pb );
  280. #endif
  281. CPropRecord& GetPrimaryPropRecord() { return _PrimaryRecord; }
  282. CPropRecord& GetSecondaryPropRecord() { return _SecondaryRecord; }
  283. private:
  284. //
  285. // IMPORTANT: Don't change the order of these declarations. _PrimaryRecord
  286. // should precede _SecondaryRecord.
  287. // The order is used in the construction of this class.
  288. //
  289. CPropRecord _PrimaryRecord;
  290. CPropRecord _SecondaryRecord;
  291. };
  292. //+-------------------------------------------------------------------------
  293. //
  294. // Member: CCompositePropRecord::CCompositePropRecord, public
  295. //
  296. // Synopsis: Takes all locks required to hold the two top-level records
  297. // open until destruction.
  298. //
  299. // Arguments: [wid] -- Workid of record to open.
  300. // [store] -- Property store manager.
  301. //
  302. // History: 22-Oct-97 KrishnaN Created
  303. //
  304. //--------------------------------------------------------------------------
  305. //
  306. // IMPORTANT ASSUMPTION: _PrimaryRecord is constructed before _SecondaryRecord.
  307. //
  308. inline CCompositePropRecord::CCompositePropRecord( WORKID wid,
  309. CPropStoreManager & store )
  310. : _PrimaryRecord( wid, store.GetPrimaryStore()),
  311. _SecondaryRecord(store.GetSecondaryTopLevelWid(wid, _PrimaryRecord),
  312. store.GetSecondaryStore())
  313. {
  314. }
  315. //+-------------------------------------------------------------------------
  316. //
  317. // Member: CCompositePropRecord::operator new, public
  318. //
  319. // Synopsis: Special operator new
  320. //
  321. // Arguments: [size] -- Size of allocation
  322. // [pb] -- Pre-allocated memory
  323. //
  324. // History: 22-Oct-97 KrishnaN Created
  325. //
  326. //--------------------------------------------------------------------------
  327. void * CCompositePropRecord::operator new( size_t size, BYTE * pb )
  328. {
  329. Win4Assert( 0 == ( ((ULONG_PTR)pb) & 0x7 ) );
  330. if( 0 == pb )
  331. THROW( CException( E_OUTOFMEMORY ) );
  332. return pb;
  333. }
  334. //+-------------------------------------------------------------------------
  335. //
  336. // Member: CCompositePropRecord::operator delete, public
  337. //
  338. // Synopsis: Special operator delete
  339. //
  340. // Arguments: [p] -- Pointer to "delete"
  341. //
  342. // History: 22-Oct-97 KrishnaN Created
  343. //
  344. //--------------------------------------------------------------------------
  345. void CCompositePropRecord::operator delete( void * p )
  346. {
  347. }
  348. #if _MSC_VER >= 1200
  349. void CCompositePropRecord::operator delete( void * p, BYTE * pb ) {}
  350. #endif
  351. //+-------------------------------------------------------------------------
  352. //
  353. // Class: CPropRecordForWrites
  354. //
  355. // Purpose: Encapsulates long-term write access to single record of
  356. // property store.
  357. //
  358. // History: 17-Mar-98 KrishnaN Created
  359. //
  360. //--------------------------------------------------------------------------
  361. class CPropRecordForWrites : public CPropRecordNoLock
  362. {
  363. public:
  364. inline CPropRecordForWrites( WORKID wid, CPropertyStore & store );
  365. private:
  366. friend class CPropertyStore;
  367. CWriteAccess _writeLock;
  368. CLockRecordForWrite _lock;
  369. };
  370. //+-------------------------------------------------------------------------
  371. //
  372. // Member: CPropRecordForWrites::CPropRecordForWrites, public
  373. //
  374. // Synopsis: Takes all locks required to hold record open for write until
  375. // destruction.
  376. //
  377. // Arguments: [wid] -- Workid of record to open.
  378. // [store] -- Property store.
  379. //
  380. // History: 17-Mar-98 KrishnaN Created
  381. //
  382. //--------------------------------------------------------------------------
  383. inline CPropRecordForWrites::CPropRecordForWrites( WORKID wid, CPropertyStore & store )
  384. : CPropRecordNoLock(wid, store, TRUE),
  385. _writeLock( store._rwAccess ),
  386. _lock( store, _wid )
  387. {
  388. }
  389. //+-------------------------------------------------------------------------
  390. //
  391. // Class: CPrimaryPropRecordForWrites
  392. //
  393. // Purpose: Encapsulates long-term access to a top-level record
  394. // of property store.
  395. //
  396. // History: 2-Jan-99 dlee Created
  397. //
  398. //--------------------------------------------------------------------------
  399. class CPrimaryPropRecordForWrites
  400. {
  401. public:
  402. CPrimaryPropRecordForWrites( WORKID wid,
  403. CPropStoreManager & store,
  404. CMutexSem & mutex )
  405. : _lock( mutex ),
  406. _PrimaryRecord( wid, store.GetPrimaryStore())
  407. {
  408. }
  409. void * operator new( size_t size, BYTE * pb )
  410. {
  411. Win4Assert( 0 == ( ((ULONG_PTR)pb) & 0x7 ) );
  412. if( 0 == pb )
  413. THROW( CException( E_OUTOFMEMORY ) );
  414. return pb;
  415. }
  416. void operator delete( void * p ) {}
  417. #if _MSC_VER >= 1200
  418. void operator delete( void * p, BYTE * pb ) {}
  419. #endif
  420. CPropRecordForWrites & GetPrimaryPropRecord() { return _PrimaryRecord; }
  421. private:
  422. CLock _lock;
  423. CPropRecordForWrites _PrimaryRecord;
  424. };
  425. //+-------------------------------------------------------------------------
  426. //
  427. // Class: CCompositePropRecordForWrites
  428. //
  429. // Purpose: Encapsulates long-term access to the two top-level records
  430. // of property store.
  431. //
  432. // History: 22-Oct-97 KrishnaN Created
  433. //
  434. //--------------------------------------------------------------------------
  435. class CCompositePropRecordForWrites
  436. {
  437. public:
  438. inline CCompositePropRecordForWrites( WORKID wid,
  439. CPropStoreManager & store,
  440. CMutexSem & mutex );
  441. inline void * operator new( size_t size, BYTE * pb );
  442. inline void operator delete( void * p );
  443. #if _MSC_VER >= 1200
  444. inline void operator delete( void * p, BYTE * pb );
  445. #endif
  446. inline CPropRecordForWrites& GetPrimaryPropRecord() { return _PrimaryRecord; }
  447. inline CPropRecordForWrites& GetSecondaryPropRecord() { return _SecondaryRecord; }
  448. private:
  449. //
  450. // IMPORTANT: Don't change the order of these declarations. _PrimaryRecord
  451. // should precede _SecondaryRecord.
  452. // The order is used in the construction of this class.
  453. //
  454. CLock _lock;
  455. CPropRecordForWrites _PrimaryRecord;
  456. CPropRecordForWrites _SecondaryRecord;
  457. };
  458. //+-------------------------------------------------------------------------
  459. //
  460. // Member: CCompositePropRecordForWrites::CCompositePropRecordForWrites, public
  461. //
  462. // Synopsis: Takes all locks required to hold the two top-level records
  463. // open until destruction.
  464. //
  465. // Arguments: [wid] -- Workid of record to open.
  466. // [store] -- Property store manager.
  467. //
  468. // History: 22-Oct-97 KrishnaN Created
  469. //
  470. //--------------------------------------------------------------------------
  471. //
  472. // IMPORTANT ASSUMPTION: _PrimaryRecord is constructed before _SecondaryRecord.
  473. //
  474. inline CCompositePropRecordForWrites::CCompositePropRecordForWrites(
  475. WORKID wid,
  476. CPropStoreManager & store,
  477. CMutexSem & mutex )
  478. : _lock( mutex ),
  479. _PrimaryRecord( wid, store.GetPrimaryStore()),
  480. _SecondaryRecord(store.GetSecondaryTopLevelWid(wid, _PrimaryRecord),
  481. store.GetSecondaryStore())
  482. {
  483. }
  484. //+-------------------------------------------------------------------------
  485. //
  486. // Member: CCompositePropRecordForWrites::operator new, public
  487. //
  488. // Synopsis: Special operator new
  489. //
  490. // Arguments: [size] -- Size of allocation
  491. // [pb] -- Pre-allocated memory
  492. //
  493. // History: 22-Oct-97 KrishnaN Created
  494. //
  495. //--------------------------------------------------------------------------
  496. void * CCompositePropRecordForWrites::operator new( size_t size, BYTE * pb )
  497. {
  498. Win4Assert( 0 == ( ((ULONG_PTR)pb) & 0x7 ) );
  499. if( 0 == pb )
  500. THROW( CException( E_OUTOFMEMORY ) );
  501. return pb;
  502. }
  503. //+-------------------------------------------------------------------------
  504. //
  505. // Member: CCompositePropRecordForWrites::operator delete, public
  506. //
  507. // Synopsis: Special operator delete
  508. //
  509. // Arguments: [p] -- Pointer to "delete"
  510. //
  511. // History: 22-Oct-97 KrishnaN Created
  512. //
  513. //--------------------------------------------------------------------------
  514. void CCompositePropRecordForWrites::operator delete( void * p )
  515. {
  516. }
  517. #if _MSC_VER >= 1200
  518. void CCompositePropRecordForWrites::operator delete( void * p, BYTE * pb ) {}
  519. #endif