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.

291 lines
9.8 KiB

  1. /***************************************************************************\
  2. *
  3. * File: Context.h
  4. *
  5. * Description:
  6. * This file declares the main Context used by the ResourceManager to manage
  7. * independent "work contexts".
  8. *
  9. *
  10. * History:
  11. * 4/18/2000: JStall: Created
  12. *
  13. * Copyright (C) 2000 by Microsoft Corporation. All rights reserved.
  14. *
  15. \***************************************************************************/
  16. #if !defined(SERVICES__Context_h__INCLUDED)
  17. #define SERVICES__Context_h__INCLUDED
  18. #pragma once
  19. class Context;
  20. class SubContext;
  21. class ContextPackBuilder;
  22. #if DBG
  23. class Thread;
  24. #endif // DBG
  25. /***************************************************************************\
  26. *****************************************************************************
  27. *
  28. * Context defines a pool of threads that can shared objects between the
  29. * threads. Inside DirectUser, only one thread is allowed to execute within
  30. * the context at a time UNLESS IT IS AN "NL" function. By dividing the
  31. * process into independent Context's, threads that are mostly unrelated can
  32. * operate without colliding over shared locks.
  33. *
  34. * Context objects are not created until the application explicitly calls
  35. * InitGadgets(). They can also be destroyed if the application calls
  36. * ::DeleteHandle() on the HDCONTEXT. This means that a thread may or may not
  37. * have a Context, though usually it will.
  38. *
  39. *****************************************************************************
  40. \***************************************************************************/
  41. class Context : public BaseObject
  42. {
  43. public:
  44. Context();
  45. ~Context();
  46. static HRESULT Build(INITGADGET * pInit, DUserHeap * pHeap, Context ** ppctxNew);
  47. virtual BOOL xwDeleteHandle();
  48. protected:
  49. virtual void xwDestroy();
  50. public:
  51. void xwPreDestroyNL();
  52. // BaseObject Interface
  53. public:
  54. virtual HandleType GetHandleType() const { return htContext; }
  55. virtual UINT GetHandleMask() const { return 0; }
  56. // Operations
  57. public:
  58. enum ESlot {
  59. slCore = 0, // Core
  60. slMotion, // Motions
  61. slCOUNT, // Number of sub-contexts
  62. };
  63. inline void MarkOrphaned();
  64. inline BOOL IsOrphanedNL() const;
  65. inline void Enter(); // Take shared Context lock
  66. inline void Leave(); // Release shared Context lock
  67. inline void Leave(BOOL fOldEnableDefer, BOOL * pfPending);
  68. #if DBG_CHECK_CALLBACKS
  69. inline void BeginCallback();
  70. inline void EndCallback();
  71. #endif
  72. inline void BeginReadOnly();
  73. inline void EndReadOnly();
  74. inline BOOL IsReadOnly() const;
  75. inline UINT GetThreadMode() const;
  76. inline UINT GetPerfMode() const;
  77. inline DUserHeap * GetHeap() const;
  78. inline SubContext* GetSC(ESlot slot) const;
  79. void AddCurrentThread();
  80. inline BOOL IsEnableDefer() const;
  81. inline void EnableDefer(BOOL fEnable, BOOL * pfOld);
  82. inline void MarkPending();
  83. DWORD xwOnIdleNL(); // Idle time processing
  84. #if DBG_CHECK_CALLBACKS
  85. int m_cLiveObjects; // Live objects outstanding
  86. int m_cTotalObjects; // Total objects allocated
  87. #endif
  88. // Implementation
  89. #if DBG
  90. public:
  91. virtual void DEBUG_AssertValid() const;
  92. #endif
  93. // Data
  94. protected:
  95. #if DBG
  96. Thread * m_DEBUG_pthrLock; // DEBUG: Thread that locked Context
  97. DWORD m_DEBUG_tidLock;// Thread ID of thread that locks
  98. #endif // DBG
  99. long m_cEnterLock; // Count of outstanding Enter()'s
  100. #if DBG_CHECK_CALLBACKS
  101. int m_cLiveCallbacks; // Outstanding callbacks
  102. #endif
  103. CritLock m_lock; // Shared access lock
  104. DUserHeap * m_pHeap; // Initialized heap
  105. UINT m_cReadOnly; // Count of pending "read-only" operations
  106. BOOL m_fPending; // Deferred callbacks are pending (GIVE THIS A FULL BOOL)
  107. BOOL m_fEnableDefer:1; // Enabled deferred messages
  108. BOOL m_fPreDestroy:1;// Have pre-destroyed the Context
  109. BOOL m_fOrphaned:1; // Context has been orphaned
  110. UINT m_nThreadMode; // Threading model for Context
  111. UINT m_nPerfMode; // Performance model
  112. SubContext* m_rgSCs[slCOUNT]; // Sub-context information
  113. };
  114. /***************************************************************************\
  115. *****************************************************************************
  116. *
  117. * SubContext defines a "extensibility" mechanism that allows individual
  118. * projects in DirectUser to provide additional data to store on the context.
  119. * To use this, the project must add a new slot in Context, derive a class
  120. * from SubContext that is created per Context instance, and derive a class
  121. * from ContextPackBuilder to register the extension.
  122. *
  123. *****************************************************************************
  124. \***************************************************************************/
  125. class SubContext
  126. {
  127. // Construction
  128. public:
  129. virtual ~SubContext() { }
  130. virtual HRESULT Create(INITGADGET * pInit) { UNREFERENCED_PARAMETER(pInit); return S_OK; }
  131. virtual void xwPreDestroyNL() PURE;
  132. // Operations
  133. public:
  134. inline void SetParent(Context * pParent);
  135. virtual DWORD xwOnIdleNL() { return INFINITE; }
  136. // Implementation
  137. #if DBG
  138. public:
  139. virtual void DEBUG_AssertValid() const;
  140. #endif
  141. // Data
  142. protected:
  143. Context * m_pParent;
  144. };
  145. /***************************************************************************\
  146. *****************************************************************************
  147. *
  148. * ContextPackBuilder registers an SubContext "extension" to be created
  149. * whenever a new Context is created. The constructor is expected to set the
  150. * slot corresponding to the ESlot value.
  151. *
  152. *****************************************************************************
  153. \***************************************************************************/
  154. class ContextPackBuilder
  155. {
  156. // Construction
  157. public:
  158. // Operations
  159. public:
  160. virtual SubContext* New(Context * pContext) PURE;
  161. static inline ContextPackBuilder *
  162. GetBuilder(Context::ESlot slot);
  163. // Data
  164. protected:
  165. static ContextPackBuilder *
  166. s_rgBuilders[Context::slCOUNT];
  167. };
  168. #define IMPLEMENT_SUBCONTEXT(id, obj) \
  169. class obj##Builder : public ContextPackBuilder \
  170. { \
  171. public: \
  172. virtual SubContext * New(Context * pParent) \
  173. { \
  174. SubContext * psc = ProcessNew(obj); \
  175. if (psc != NULL) { \
  176. psc->SetParent(pParent); \
  177. } \
  178. return psc; \
  179. } \
  180. } g_##obj##B \
  181. #define PREINIT_SUBCONTEXT(obj) \
  182. class obj##Builder; \
  183. extern obj##Builder g_##obj##B \
  184. #define INIT_SUBCONTEXT(obj) \
  185. (ContextPackBuilder *) &g_##obj##B \
  186. inline Context * GetContext();
  187. inline BOOL IsInitContext();
  188. /***************************************************************************\
  189. *****************************************************************************
  190. *
  191. * ContextLock provides a convenient mechanism of locking the Context and
  192. * automatically unlocking when finished. Because ContextLock perform
  193. * additional Context-specific actions, it is important to use a ContextLock
  194. * to lock a Context instead of using an ObjectLock.
  195. *
  196. *****************************************************************************
  197. \***************************************************************************/
  198. class ContextLock
  199. {
  200. public:
  201. enum EnableDefer
  202. {
  203. edNone = FALSE, // Enabled deferred messages
  204. edDefer = TRUE, // Don't enable deferred messages
  205. };
  206. inline ContextLock();
  207. inline ~ContextLock();
  208. BOOL LockNL(ContextLock::EnableDefer ed, Context * pctxThread = GetContext());
  209. // Data (public access)
  210. Context * pctx;
  211. BOOL fOldDeferred;
  212. };
  213. class ReadOnlyLock
  214. {
  215. public:
  216. inline ReadOnlyLock(Context * pctxThread = GetContext());
  217. inline ~ReadOnlyLock();
  218. Context * pctx;
  219. };
  220. #if DBG_CHECK_CALLBACKS
  221. #define BEGIN_CALLBACK() \
  222. __try { \
  223. if (!IsInitThread()) { \
  224. AlwaysPromptInvalid("DirectUser has been uninitialized before processing a callback (1)"); \
  225. } \
  226. GetContext()->BeginCallback(); \
  227. #define END_CALLBACK() \
  228. } __finally { \
  229. GetContext()->EndCallback(); \
  230. if (!IsInitThread()) { \
  231. AlwaysPromptInvalid("DirectUser has been uninitialized while processing a Message (2)"); \
  232. } \
  233. }
  234. #endif // DBG_CHECK_CALLBACKS
  235. #include "Context.inl"
  236. #endif // SERVICES__Context_h__INCLUDED