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.

903 lines
22 KiB

  1. //+--------------------------------------------------------------
  2. //
  3. // Microsoft Windows
  4. // Copyright (C) Microsoft Corporation, 1992 - 1992.
  5. //
  6. // File: context.hxx
  7. //
  8. // Contents: Per-context things header
  9. //
  10. // Classes: CPerContext
  11. //
  12. // History: 14-Aug-92 DrewB Created
  13. //
  14. //---------------------------------------------------------------
  15. #ifndef __CONTEXT_HXX__
  16. #define __CONTEXT_HXX__
  17. #include <filest.hxx>
  18. #include <cntxlist.hxx>
  19. #if WIN32 >= 100
  20. #include <entry.hxx>
  21. #include <df32.hxx>
  22. #endif
  23. #ifdef MULTIHEAP
  24. #include <smalloc.hxx>
  25. extern SCODE DfSyncSharedMemory(ULONG ulHeapName);
  26. #else
  27. extern SCODE DfSyncSharedMemory(void);
  28. #endif
  29. interface ILockBytes;
  30. // Maximum length of a mutex name for contexts
  31. #define CONTEXT_MUTEX_NAME_LENGTH 32
  32. //+--------------------------------------------------------------
  33. //
  34. // Class: CPerContext (pc)
  35. //
  36. // Purpose: Holds per-context information
  37. //
  38. // Interface: See below
  39. //
  40. // History: 14-Aug-92 DrewB Created
  41. //
  42. //---------------------------------------------------------------
  43. class CGlobalContext;
  44. SAFE_DFBASED_PTR(CBasedGlobalContextPtr, CGlobalContext);
  45. class CPerContext : public CContext
  46. {
  47. public:
  48. inline CPerContext(
  49. IMalloc *pMalloc,
  50. ILockBytes *plkbBase,
  51. CFileStream *pfstDirty,
  52. ILockBytes *plkbOriginal,
  53. ULONG ulOpenLock);
  54. inline CPerContext(IMalloc *pMalloc);
  55. inline void SetILBInfo(ILockBytes *plkbBase,
  56. CFileStream *pfstDirty,
  57. ILockBytes *plkbOriginal,
  58. ULONG ulOpenLock);
  59. inline void SetLockInfo(BOOL fTakeLock, DFLAGS dfOpenLock);
  60. inline SCODE InitNewContext(void);
  61. inline SCODE InitFromGlobal(CGlobalContext *pgc);
  62. ~CPerContext(void);
  63. inline LONG AddRef(void);
  64. inline LONG Release(void);
  65. #ifdef ASYNC
  66. inline LONG AddRefSharedMem(void);
  67. inline LONG ReleaseSharedMem(void);
  68. inline LONG DecRef(void);
  69. #endif
  70. inline ILockBytes *GetBase(void) const;
  71. inline CFileStream *GetDirty(void) const;
  72. inline ILockBytes *GetOriginal(void) const;
  73. inline ULONG GetOpenLock(void) const;
  74. inline ContextId GetContextId(void) const;
  75. inline CGlobalContext *GetGlobal(void) const;
  76. inline IMalloc * GetMalloc(void) const;
  77. inline void SetOpenLock(ULONG ulOpenLock);
  78. inline SCODE TakeSem(DWORD dwTimeout);
  79. inline void ReleaseSem(void);
  80. #ifdef MULTIHEAP
  81. inline SCODE SetAllocatorState(CPerContext **pppcPrev, CSmAllocator *psma);
  82. inline SCODE GetThreadAllocatorState();
  83. inline CSmAllocator *SetThreadAllocatorState(CPerContext **pppcPrev);
  84. inline void UntakeSem() { ReleaseSem(); }; // workaround macro in docfilep
  85. #endif
  86. #ifdef ASYNC
  87. inline IFillInfo * GetFillInfo(void) const;
  88. inline HANDLE GetNotificationEvent(void) const;
  89. SCODE InitNotificationEvent(ILockBytes *plkbBase);
  90. #if DBG == 1
  91. inline BOOL HaveMutex(void);
  92. #endif
  93. #endif
  94. void Close(void);
  95. #ifdef DIRECTWRITERLOCK
  96. ULONG * GetRecursionCount () {return &_cRecursion; };
  97. #endif
  98. #ifdef MULTIHEAP
  99. BYTE * GetHeapBase () { return _pbBase; };
  100. #endif
  101. inline BOOL IsHandleValid ();
  102. private:
  103. ILockBytes *_plkbBase;
  104. CFileStream *_pfstDirty;
  105. ILockBytes *_plkbOriginal;
  106. ULONG _ulOpenLock;
  107. CBasedGlobalContextPtr _pgc;
  108. LONG _cReferences;
  109. #ifdef ASYNC
  110. LONG _cRefSharedMem;
  111. #endif
  112. IMalloc * const _pMalloc;
  113. #ifdef ASYNC
  114. IFillInfo *_pfi;
  115. HANDLE _hNotificationEvent;
  116. #endif
  117. #ifdef MULTIHEAP
  118. CSharedMemoryBlock *_psmb; // heap object
  119. BYTE * _pbBase; // base address of heap
  120. ULONG _ulHeapName; // name of shared mem region
  121. #endif
  122. #if WIN32 >= 100
  123. CDfMutex _dmtx;
  124. #endif
  125. #ifdef DIRECTWRITERLOCK
  126. ULONG _cRecursion; // recursion count of writers
  127. #endif
  128. };
  129. SAFE_DFBASED_PTR(CBasedPerContextPtr, CPerContext);
  130. //+---------------------------------------------------------------------------
  131. //
  132. // Class: CGlobalContext
  133. //
  134. // Purpose: Holds context-insensitive information
  135. //
  136. // Interface: See below
  137. //
  138. // History: 26-Oct-92 DrewB Created
  139. //
  140. //----------------------------------------------------------------------------
  141. class CGlobalContext : public CContextList
  142. {
  143. public:
  144. inline CGlobalContext(IMalloc *pMalloc);
  145. inline void SetLockInfo(BOOL fTakeLock,
  146. DFLAGS dfOpenLock);
  147. DECLARE_CONTEXT_LIST(CPerContext);
  148. inline BOOL TakeLock(void) const;
  149. inline DFLAGS GetOpenLockFlags(void) const;
  150. inline IMalloc *GetMalloc(void) const;
  151. #if WIN32 >= 100
  152. inline void GetMutexName(TCHAR *ptcsName);
  153. #ifdef ASYNC
  154. inline void GetEventName(TCHAR *ptcsName);
  155. #endif
  156. #endif
  157. private:
  158. BOOL _fTakeLock;
  159. DFLAGS _dfOpenLock;
  160. IMalloc * const _pMalloc;
  161. #if WIN32 >= 100
  162. LARGE_INTEGER _luidMutexName;
  163. #endif
  164. };
  165. inline CGlobalContext::CGlobalContext(IMalloc *pMalloc)
  166. : _pMalloc(pMalloc)
  167. {
  168. #if WIN32 >= 100
  169. // Use a luid as the name for the mutex because the 64-bit
  170. // luid generator is guaranteed to produce machine-wide unique
  171. // values each time it is called, so if we use one for our mutex
  172. // name we know it won't collide with any others
  173. #if !defined(MULTIHEAP)
  174. _luidMutexName.QuadPart = PBasicEntry::GetNewLuid(pMalloc);
  175. #else
  176. if (DFBASEPTR == NULL) // task memory support
  177. {
  178. LUID luid;
  179. AllocateLocallyUniqueId (&luid);
  180. _luidMutexName.LowPart = luid.LowPart;
  181. _luidMutexName.HighPart = luid.HighPart;
  182. }
  183. else
  184. {
  185. _luidMutexName.QuadPart = g_smAllocator.GetHeapName();
  186. }
  187. #endif
  188. #endif
  189. }
  190. inline void CGlobalContext::SetLockInfo(BOOL fTakeLock, DFLAGS dfOpenLock)
  191. {
  192. _fTakeLock = fTakeLock;
  193. _dfOpenLock = dfOpenLock;
  194. }
  195. //+--------------------------------------------------------------
  196. //
  197. // Member: CGlobalContext::TakeLock, public
  198. //
  199. // Synopsis: Returns whether locks should be taken or not
  200. //
  201. // History: 04-Sep-92 DrewB Created
  202. //
  203. //---------------------------------------------------------------
  204. inline BOOL CGlobalContext::TakeLock(void) const
  205. {
  206. return _fTakeLock;
  207. }
  208. //+--------------------------------------------------------------
  209. //
  210. // Member: CGlobalContext::GetOpenLockFlags, public
  211. //
  212. // Synopsis: Returns the open lock flags
  213. //
  214. // History: 04-Sep-92 DrewB Created
  215. //
  216. //---------------------------------------------------------------
  217. inline DFLAGS CGlobalContext::GetOpenLockFlags(void) const
  218. {
  219. return _dfOpenLock;
  220. }
  221. //+--------------------------------------------------------------
  222. //
  223. // Member: CGlobalContext::GetMalloc, public
  224. //
  225. // Synopsis: Returns the allocator associated with this global context
  226. //
  227. // History: 05-May-93 AlexT Created
  228. //
  229. //---------------------------------------------------------------
  230. inline IMalloc *CGlobalContext::GetMalloc(void) const
  231. {
  232. return (IMalloc *)_pMalloc;
  233. }
  234. //+---------------------------------------------------------------------------
  235. //
  236. // Member: CGlobalContext::GetMutexName, public
  237. //
  238. // Synopsis: Returns the name to use for the mutex for this tree
  239. //
  240. // Arguments: [ptcsName] - Name return
  241. //
  242. // Modifies: [ptcsName]
  243. //
  244. // History: 09-Oct-93 DrewB Created
  245. //
  246. // Notes: [ptcsName] should have space for at least
  247. // CONTEXT_MUTEX_NAME_LENGTH characters
  248. //
  249. //----------------------------------------------------------------------------
  250. #if WIN32 >= 100
  251. inline void CGlobalContext::GetMutexName(TCHAR *ptcsName)
  252. {
  253. wsprintfT(ptcsName, TSTR("OleDfRoot%X%08lX"), _luidMutexName.HighPart,
  254. _luidMutexName.LowPart);
  255. }
  256. #ifdef ASYNC
  257. inline void CGlobalContext::GetEventName(TCHAR *ptcsName)
  258. {
  259. wsprintfT(ptcsName, TSTR("OleAsyncE%X%08lX"), _luidMutexName.HighPart,
  260. _luidMutexName.LowPart);
  261. }
  262. #endif // ASYNC
  263. #endif
  264. inline void CPerContext::SetILBInfo(ILockBytes *plkbBase,
  265. CFileStream *pfstDirty,
  266. ILockBytes *plkbOriginal,
  267. ULONG ulOpenLock)
  268. {
  269. _plkbBase = plkbBase;
  270. _pfstDirty = pfstDirty;
  271. _plkbOriginal = plkbOriginal;
  272. _ulOpenLock = ulOpenLock;
  273. #ifdef ASYNC
  274. _pfi = NULL;
  275. if (_plkbBase)
  276. {
  277. IFillInfo *pfi;
  278. HRESULT hr = _plkbBase->QueryInterface(IID_IFillInfo,
  279. (void **)&pfi);
  280. if (SUCCEEDED(hr))
  281. {
  282. if (SUCCEEDED(InitNotificationEvent(_plkbBase)))
  283. {
  284. _pfi = pfi;
  285. }
  286. else
  287. {
  288. pfi->Release();
  289. }
  290. }
  291. }
  292. #endif
  293. }
  294. //+--------------------------------------------------------------
  295. //
  296. // Member: CPerContext::CPerContext, public
  297. //
  298. // Synopsis: Constructor
  299. //
  300. // Arguments: [plkbBase] - Base lstream
  301. // [pfstDirty] - Dirty lstream
  302. // [plkbOriginal] - Original base lstream for
  303. // independent copies
  304. // [ulOpenLock] - Open lock for base lstream
  305. //
  306. // History: 14-Aug-92 DrewB Created
  307. // 18-May-93 AlexT Added pMalloc
  308. //
  309. //---------------------------------------------------------------
  310. inline CPerContext::CPerContext(
  311. IMalloc *pMalloc,
  312. ILockBytes *plkbBase,
  313. CFileStream *pfstDirty,
  314. ILockBytes *plkbOriginal,
  315. ULONG ulOpenLock)
  316. : _pMalloc(pMalloc)
  317. {
  318. _plkbBase = plkbBase;
  319. _pfstDirty = pfstDirty;
  320. _plkbOriginal = plkbOriginal;
  321. _ulOpenLock = ulOpenLock;
  322. _cReferences = 1;
  323. #ifdef ASYNC
  324. _cRefSharedMem = 1;
  325. #endif
  326. _pgc = NULL;
  327. #ifdef MULTIHEAP
  328. g_smAllocator.GetState(&_psmb, &_pbBase, &_ulHeapName);
  329. #endif
  330. #ifdef DIRECTWRITERLOCK
  331. _cRecursion = 0; // recursion count of writers
  332. #endif
  333. }
  334. //+--------------------------------------------------------------
  335. //
  336. // Member: CPerContext::CPerContext, public
  337. //
  338. // Synopsis: Constructor for a temporary stack-based object
  339. // This is only used for unmarshaling, since we
  340. // need a percontext to own the heap before the
  341. // actual percontext is unmarshaled
  342. //
  343. // Arguments: [pMalloc] - Base IMalloc
  344. //
  345. // History: 29-Nov-95 HenryLee Created
  346. //
  347. //---------------------------------------------------------------
  348. inline CPerContext::CPerContext(IMalloc *pMalloc) : _pMalloc(pMalloc)
  349. {
  350. #ifdef MULTIHEAP
  351. g_smAllocator.GetState(&_psmb, &_pbBase, &_ulHeapName);
  352. #endif
  353. _plkbBase = _plkbOriginal = NULL;
  354. _pfstDirty = NULL;
  355. _ulOpenLock = 0;
  356. _cReferences = 1;
  357. #ifdef ASYNC
  358. _cRefSharedMem = 1;
  359. #endif
  360. _pgc = NULL;
  361. #ifdef ASYNC
  362. _pfi = NULL;
  363. _hNotificationEvent = INVALID_HANDLE_VALUE;
  364. #endif
  365. #ifdef DIRECTWRITERLOCK
  366. _cRecursion = 0; // recursion count of writers
  367. #endif
  368. }
  369. #ifdef ASYNC
  370. inline LONG CPerContext::AddRefSharedMem(void)
  371. {
  372. olAssert(_cRefSharedMem >= _cReferences);
  373. AtomicInc(&_cRefSharedMem);
  374. olAssert(_cRefSharedMem >= _cReferences);
  375. return _cRefSharedMem;
  376. }
  377. inline LONG CPerContext::ReleaseSharedMem(void)
  378. {
  379. LONG lRet;
  380. olAssert(_cRefSharedMem > 0);
  381. olAssert(_cRefSharedMem >= _cReferences);
  382. lRet = AtomicDec(&_cRefSharedMem);
  383. if ((_cReferences == 0) && (_cRefSharedMem == 0))
  384. delete this;
  385. return lRet;
  386. }
  387. inline LONG CPerContext::DecRef(void)
  388. {
  389. olAssert(_cRefSharedMem >= _cReferences);
  390. AtomicDec(&_cReferences);
  391. olAssert(_cRefSharedMem >= _cReferences);
  392. return _cReferences;
  393. }
  394. #endif
  395. //+---------------------------------------------------------------------------
  396. //
  397. // Member: CPerContext::AddRef, public
  398. //
  399. // Synopsis: Increments the ref count
  400. //
  401. // History: 27-Oct-92 DrewB Created
  402. //
  403. //----------------------------------------------------------------------------
  404. inline LONG CPerContext::AddRef(void)
  405. {
  406. #ifdef ASYNC
  407. olAssert(_cRefSharedMem >= _cReferences);
  408. AddRefSharedMem();
  409. #endif
  410. AtomicInc(&_cReferences);
  411. #ifdef ASYNC
  412. olAssert(_cRefSharedMem >= _cReferences);
  413. #endif
  414. return _cReferences;
  415. }
  416. //+---------------------------------------------------------------------------
  417. //
  418. // Member: CPerContext::Release, public
  419. //
  420. // Synopsis: Decrements the ref count
  421. //
  422. // History: 27-Oct-92 DrewB Created
  423. //
  424. //----------------------------------------------------------------------------
  425. inline LONG CPerContext::Release(void)
  426. {
  427. LONG lRet;
  428. olAssert(_cReferences > 0);
  429. #ifdef ASYNC
  430. olAssert(_cRefSharedMem >= _cReferences);
  431. #endif
  432. lRet = AtomicDec(&_cReferences);
  433. if (lRet == 0)
  434. {
  435. #ifdef ASYNC
  436. if (_plkbBase != NULL)
  437. {
  438. Close();
  439. }
  440. #else
  441. delete this;
  442. #endif
  443. }
  444. #ifdef ASYNC
  445. olAssert(_cRefSharedMem >= _cReferences);
  446. //Note: If the object is going to get deleted, it will happen
  447. // in the ReleaseSharedMem call.
  448. lRet = ReleaseSharedMem();
  449. #endif
  450. return lRet;
  451. }
  452. //+--------------------------------------------------------------
  453. //
  454. // Member: CPerContext::GetBase, public
  455. //
  456. // Synopsis: Returns the base
  457. //
  458. // History: 14-Aug-92 DrewB Created
  459. //
  460. //---------------------------------------------------------------
  461. inline ILockBytes *CPerContext::GetBase(void) const
  462. {
  463. return _plkbBase;
  464. }
  465. //+--------------------------------------------------------------
  466. //
  467. // Member: CPerContext::GetDirty, public
  468. //
  469. // Synopsis: Returns the dirty
  470. //
  471. // History: 14-Aug-92 DrewB Created
  472. //
  473. //---------------------------------------------------------------
  474. inline CFileStream *CPerContext::GetDirty(void) const
  475. {
  476. return _pfstDirty;
  477. }
  478. //+--------------------------------------------------------------
  479. //
  480. // Member: CPerContext::GetOriginal, public
  481. //
  482. // Synopsis: Returns the Original
  483. //
  484. // History: 14-Aug-92 DrewB Created
  485. //
  486. //---------------------------------------------------------------
  487. inline ILockBytes *CPerContext::GetOriginal(void) const
  488. {
  489. return _plkbOriginal;
  490. }
  491. //+--------------------------------------------------------------
  492. //
  493. // Member: CPerContext::GetOpenLock, public
  494. //
  495. // Synopsis: Returns the open lock index
  496. //
  497. // History: 04-Sep-92 DrewB Created
  498. //
  499. //---------------------------------------------------------------
  500. inline ULONG CPerContext::GetOpenLock(void) const
  501. {
  502. return _ulOpenLock;
  503. }
  504. //+--------------------------------------------------------------
  505. //
  506. // Member: CPerContext::GetContextId, public
  507. //
  508. // Synopsis: Returns the context id
  509. //
  510. // History: 04-Sep-92 DrewB Created
  511. //
  512. //---------------------------------------------------------------
  513. inline ContextId CPerContext::GetContextId(void) const
  514. {
  515. return ctxid;
  516. }
  517. //+--------------------------------------------------------------
  518. //
  519. // Member: CPerContext::GetMalloc, public
  520. //
  521. // Synopsis: Returns the IMalloc pointer
  522. //
  523. // History: 04-Apr-96 PhilipLa Created
  524. //
  525. //---------------------------------------------------------------
  526. inline IMalloc * CPerContext::GetMalloc(void) const
  527. {
  528. return _pMalloc;
  529. }
  530. //+--------------------------------------------------------------
  531. //
  532. // Member: CPerContext::GetGlobal, public
  533. //
  534. // Synopsis: Returns the global context
  535. //
  536. // History: 04-Sep-92 DrewB Created
  537. //
  538. //---------------------------------------------------------------
  539. inline CGlobalContext *CPerContext::GetGlobal(void) const
  540. {
  541. return BP_TO_P(CGlobalContext *, _pgc);
  542. }
  543. inline void CPerContext::SetLockInfo(BOOL fTakeLock,
  544. DFLAGS dfOpenLock)
  545. {
  546. _pgc->SetLockInfo(fTakeLock, dfOpenLock);
  547. }
  548. //+---------------------------------------------------------------------------
  549. //
  550. // Member: CPerContext::InitNewContext, public
  551. //
  552. // Synopsis: Creates a new context and context list
  553. //
  554. // Returns: Appropriate status code
  555. //
  556. // History: 27-Oct-92 DrewB Created
  557. //
  558. //----------------------------------------------------------------------------
  559. inline SCODE CPerContext::InitNewContext(void)
  560. {
  561. SCODE sc;
  562. CGlobalContext *pgcTemp;
  563. sc = (pgcTemp = new (_pMalloc) CGlobalContext(_pMalloc)) == NULL ?
  564. STG_E_INSUFFICIENTMEMORY : S_OK;
  565. if (SUCCEEDED(sc))
  566. {
  567. _pgc = P_TO_BP(CBasedGlobalContextPtr, pgcTemp);
  568. #if WIN32 >= 100
  569. TCHAR atcMutexName[CONTEXT_MUTEX_NAME_LENGTH];
  570. _pgc->GetMutexName(atcMutexName);
  571. sc = _dmtx.Init(atcMutexName);
  572. if (FAILED(sc))
  573. {
  574. _pgc->Release();
  575. _pgc = NULL;
  576. }
  577. else
  578. #endif
  579. _pgc->Add(this);
  580. }
  581. return sc;
  582. }
  583. //+---------------------------------------------------------------------------
  584. //
  585. // Member: CPerContext::InitFromGlobal, public
  586. //
  587. // Synopsis: Adds a context to the context list
  588. //
  589. // Returns: Appropriate status code
  590. //
  591. // History: 27-Oct-92 DrewB Created
  592. //
  593. //----------------------------------------------------------------------------
  594. inline SCODE CPerContext::InitFromGlobal(CGlobalContext *pgc)
  595. {
  596. SCODE sc;
  597. sc = S_OK;
  598. #if WIN32 >= 100
  599. TCHAR atcMutexName[CONTEXT_MUTEX_NAME_LENGTH];
  600. pgc->GetMutexName(atcMutexName);
  601. sc = _dmtx.Init(atcMutexName);
  602. #endif
  603. if (SUCCEEDED(sc))
  604. {
  605. _pgc = P_TO_BP(CBasedGlobalContextPtr, pgc);
  606. _pgc->AddRef();
  607. _pgc->Add(this);
  608. }
  609. return sc;
  610. }
  611. //+---------------------------------------------------------------------------
  612. //
  613. // Member: CPerContext::SetOpenLock, public
  614. //
  615. // Synopsis: Sets the open lock
  616. //
  617. // History: 13-Jan-93 DrewB Created
  618. //
  619. //----------------------------------------------------------------------------
  620. inline void CPerContext::SetOpenLock(ULONG ulOpenLock)
  621. {
  622. _ulOpenLock = ulOpenLock;
  623. }
  624. //+---------------------------------------------------------------------------
  625. //
  626. // Member: CPerContext::TakeSem, public
  627. //
  628. // Synopsis: Takes the mutex
  629. //
  630. // Arguments: [dwTimeout] - Timeout
  631. //
  632. // Returns: Appropriate status code
  633. //
  634. // History: 09-Oct-93 DrewB Created
  635. //
  636. //----------------------------------------------------------------------------
  637. inline SCODE CPerContext::TakeSem(DWORD dwTimeout)
  638. {
  639. #if WIN32 >= 100
  640. SCODE sc;
  641. olChk(_dmtx.Take(dwTimeout));
  642. #ifdef ONETHREAD
  643. olChkTo(EH_Tree, s_dmtxProcess.Take(dwTimeout));
  644. #endif
  645. #ifdef MULTIHEAP
  646. if (_psmb && !_psmb->IsSynced())
  647. {
  648. olChkTo(EH_Process, _psmb->Sync());
  649. }
  650. #else
  651. olChkTo(EH_Process, DfSyncSharedMemory());
  652. #endif
  653. EH_Err:
  654. return sc;
  655. EH_Process:
  656. #ifdef ONETHREAD
  657. s_dmtxProcess.Release();
  658. EH_Tree:
  659. #endif
  660. _dmtx.Release();
  661. return sc;
  662. #else
  663. return S_OK;
  664. #endif
  665. }
  666. //+---------------------------------------------------------------------------
  667. //
  668. // Member: CPerContext::ReleaseSem, public
  669. //
  670. // Synopsis: Releases the mutex
  671. //
  672. // History: 09-Oct-93 DrewB Created
  673. //
  674. //----------------------------------------------------------------------------
  675. inline void CPerContext::ReleaseSem(void)
  676. {
  677. #if WIN32 >= 100
  678. #ifdef ONETHREAD
  679. s_dmtxProcess.Release();
  680. #endif
  681. _dmtx.Release();
  682. #endif
  683. }
  684. #ifdef MULTIHEAP
  685. //+-------------------------------------------------------------------------
  686. //
  687. // Member: CPerContext::SetThreadAllocatorState, public
  688. //
  689. // Synopsis: set current thread's allocator to be this percontext
  690. //
  691. // History: 29-Nov-95 HenryLee Created
  692. //
  693. //--------------------------------------------------------------------------
  694. inline CSmAllocator *CPerContext::SetThreadAllocatorState(CPerContext**pppcPrev)
  695. {
  696. CSmAllocator *pSmAllocator = &g_smAllocator;
  697. pSmAllocator->SetState(_psmb, _pbBase, _ulHeapName, pppcPrev, this);
  698. return pSmAllocator;
  699. }
  700. //+---------------------------------------------------------------------------
  701. //
  702. // Member: CPerContext::SetAllocatorState, public
  703. //
  704. // Synopsis: sets owner of shared memory heap to this percontext
  705. // remembers the previous context owner
  706. //
  707. // History: 29-Nov-95 HenryLee Created
  708. //
  709. //----------------------------------------------------------------------------
  710. inline SCODE CPerContext::SetAllocatorState (CPerContext **pppcPrev,
  711. CSmAllocator *pSmAllocator)
  712. {
  713. pSmAllocator->SetState(_psmb, _pbBase, _ulHeapName, pppcPrev, this);
  714. return S_OK;
  715. }
  716. //+--------------------------------------------------------------
  717. //
  718. // Member: CPerContext::GetThreadAllocatorState, public
  719. //
  720. // Synopsis: retrives the current thread's allocator state
  721. //
  722. // Arguments: none
  723. //
  724. // History: 29-Nov-95 HenryLee Created
  725. //
  726. //---------------------------------------------------------------
  727. inline SCODE CPerContext::GetThreadAllocatorState()
  728. {
  729. g_smAllocator.GetState(&_psmb, &_pbBase, &_ulHeapName);
  730. return S_OK;
  731. }
  732. //+--------------------------------------------------------------
  733. //
  734. // Class: CSafeMultiHeap
  735. //
  736. // Purpose: 1) sets and restores allocator state for those
  737. // methods that do not take the tree mutex
  738. // 2) for self-destructive methods like IStorage::Release,
  739. // IStream::Release, IEnumSTATSTG::Release, the
  740. // previous percontext may get deleted along with
  741. // whole heap, and it checks for that
  742. //
  743. // Interface: See below
  744. //
  745. // History: 29-Nov-95 HenryLee Created
  746. //
  747. //---------------------------------------------------------------
  748. class CSafeMultiHeap
  749. {
  750. public:
  751. CSafeMultiHeap(CPerContext *ppc);
  752. ~CSafeMultiHeap();
  753. private:
  754. CSmAllocator *_pSmAllocator;
  755. CPerContext *_ppcPrev;
  756. };
  757. #endif // MULTIHEAP
  758. #ifdef ASYNC
  759. inline IFillInfo * CPerContext::GetFillInfo(void) const
  760. {
  761. return _pfi;
  762. }
  763. inline HANDLE CPerContext::GetNotificationEvent(void) const
  764. {
  765. return _hNotificationEvent;
  766. }
  767. #if DBG == 1
  768. inline BOOL CPerContext::HaveMutex(void)
  769. {
  770. return _dmtx.HaveMutex();
  771. }
  772. #endif // #if DBG == 1
  773. #endif // #ifdef ASYNC
  774. inline BOOL CPerContext::IsHandleValid ()
  775. {
  776. TCHAR tcsName[CONTEXT_MUTEX_NAME_LENGTH * 2];
  777. lstrcpy (tcsName, TEXT("\\BaseNamedObjects\\"));
  778. _pgc->GetMutexName(&tcsName[lstrlen(tcsName)]);
  779. BOOL fValid = _dmtx.IsHandleValid(tcsName);
  780. if (!fValid) // if this object is not valid, don't let anyone else
  781. { // use it because its per-process handles are bogus
  782. ctxid = 0;
  783. }
  784. return fValid;
  785. }
  786. #endif // #ifndef __CONTEXT_HXX__