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.

310 lines
8.3 KiB

  1. /*===================================================================
  2. Microsoft Denali
  3. Microsoft Confidential.
  4. Copyright 1997 Microsoft Corporation. All Rights Reserved.
  5. Component: Viper Integration Objects
  6. File: viperint.h
  7. Owner: DmitryR
  8. This file contains the definiton of viper integration classes
  9. ===================================================================*/
  10. #ifndef VIPERINT_H
  11. #define VIPERINT_H
  12. #include "comsvcs.h"
  13. #include "mtxpriv.h"
  14. #include "glob.h"
  15. #include "asptlb.h" // needed to define interface pointers
  16. #include "reftrace.h"
  17. #include "memcls.h"
  18. #define REFTRACE_VIPER_REQUESTS DBG
  19. class CHitObj; // forward decl
  20. /*===================================================================
  21. Transaction Support Types
  22. ===================================================================*/
  23. #define TransType DWORD
  24. #define ttUndefined 0x00000000
  25. #define ttNotSupported 0x00000001
  26. #define ttSupported 0x00000002
  27. #define ttRequired 0x00000004
  28. #define ttRequiresNew 0x00000008
  29. /*===================================================================
  30. CViperAsyncRequest class implements IMTSCall interface.
  31. Its OnCall() method does HitObj processing.
  32. This is a private class used in CViperActivity class
  33. ===================================================================*/
  34. class CViperAsyncRequest : public IServiceCall, public IAsyncErrorNotify, public CDblLink
  35. {
  36. private:
  37. LONG m_cRefs; // reference count
  38. CHitObj *m_pHitObj; // request
  39. IServiceActivity *m_pActivity;
  40. HRESULT m_hrOnError;
  41. DWORD m_dwTimeout:16;
  42. DWORD m_dwRepostAttempts:8;
  43. DWORD m_fBrowserRequest:1;
  44. DWORD m_fTestingConnection:1;
  45. DWORD m_fAsyncCallPosted:1;
  46. DWORD m_dwLastTestTimeStamp;
  47. private:
  48. CViperAsyncRequest();
  49. ~CViperAsyncRequest();
  50. HRESULT Init(CHitObj *pHitObj, IServiceActivity *pActivity);
  51. public:
  52. BOOL FBrowserRequest() { return m_fBrowserRequest; }
  53. CHitObj *PHitObj() { return m_pHitObj; }
  54. DWORD SecsSinceLastTest();
  55. void UpdateTestTimeStamp() { m_dwLastTestTimeStamp = GetTickCount(); }
  56. DWORD dwTimeout() { return m_dwTimeout; };
  57. #if REFTRACE_VIPER_REQUESTS
  58. static PTRACE_LOG gm_pTraceLog;
  59. #endif
  60. public:
  61. #ifdef DBG
  62. virtual void AssertValid() const;
  63. #else
  64. virtual void AssertValid() const {}
  65. #endif
  66. public:
  67. // IUnknown Methods
  68. STDMETHODIMP QueryInterface(REFIID iid, void **ppv);
  69. STDMETHODIMP_(ULONG) AddRef();
  70. STDMETHODIMP_(ULONG) Release();
  71. // IServiceCall Method
  72. STDMETHODIMP OnCall();
  73. // IAsyncErrorNotify
  74. STDMETHODIMP OnError(HRESULT hr);
  75. BOOL FTestingConnection() { return m_fTestingConnection; }
  76. void SetTestingConnection() { m_fTestingConnection = TRUE; }
  77. void ClearTestingConnection() { m_fTestingConnection = FALSE; }
  78. BOOL FAsyncCallPosted() { return m_fAsyncCallPosted; }
  79. void SetAsyncCallPosted() { m_fAsyncCallPosted = TRUE; }
  80. void ClearAsyncCallPosted() { m_fAsyncCallPosted = FALSE; }
  81. friend class CViperActivity;
  82. // Cache on per-class basis
  83. ACACHE_INCLASS_DEFINITIONS()
  84. };
  85. extern volatile LONG g_nViperRequests;
  86. /*===================================================================
  87. CViperActivity corresponds to a Session.
  88. It creates MTS activity, and launches async requests
  89. ===================================================================*/
  90. class CViperActivity
  91. {
  92. private:
  93. IServiceActivity *m_pActivity;
  94. DWORD m_cBind; // inited-flag + bind-to-thread count
  95. inline BOOL FInited() const { return (m_cBind > 0); }
  96. public:
  97. CViperActivity();
  98. ~CViperActivity();
  99. // Create Viper activity
  100. HRESULT Init(IUnknown *pConfig);
  101. // Clone Viper activity
  102. HRESULT InitClone(CViperActivity *pActivity);
  103. // Bind/Unbind
  104. HRESULT BindToThread();
  105. HRESULT UnBindFromThread();
  106. // Release Viper activity
  107. HRESULT UnInit();
  108. // Check if thread-bound
  109. inline BOOL FThreadBound() const { return (m_cBind > 1); }
  110. // Post async request within this activity
  111. HRESULT PostAsyncRequest(CHitObj *pHitObj);
  112. // post async request without an activity
  113. static HRESULT PostGlobalAsyncRequest(CHitObj *pHitObj);
  114. public:
  115. #ifdef DBG
  116. virtual void AssertValid() const;
  117. #else
  118. virtual void AssertValid() const {}
  119. #endif
  120. // Cache on per-class basis
  121. ACACHE_INCLASS_DEFINITIONS()
  122. };
  123. /*===================================================================
  124. Misc. Functions
  125. ===================================================================*/
  126. HRESULT ViperAttachIntrinsicsToContext
  127. (
  128. IApplicationObject *pAppln,
  129. ISessionObject *pSession = NULL,
  130. IRequest *pRequest = NULL,
  131. IResponse *pResponse = NULL,
  132. IServer *pServer = NULL
  133. );
  134. HRESULT ViperGetObjectFromContext
  135. (
  136. BSTR bstrName,
  137. IDispatch **ppdisp
  138. );
  139. HRESULT ViperGetHitObjFromContext
  140. (
  141. CHitObj **ppHitObj
  142. );
  143. HRESULT ViperCreateInstance
  144. (
  145. REFCLSID rclsid,
  146. REFIID riid,
  147. void **ppv
  148. );
  149. HRESULT ViperConfigure();
  150. HRESULT ViperConfigureMTA();
  151. HRESULT ViperConfigureSTA();
  152. /*===================================================================
  153. CViperReqManager
  154. This class manages the outstanding CViperAsyncRequest objects.
  155. With this class, we can periodically cleanup disconnected requests
  156. on the queue.
  157. ===================================================================*/
  158. class CViperReqManager
  159. {
  160. public:
  161. CViperReqManager();
  162. ~CViperReqManager() {};
  163. HRESULT Init();
  164. HRESULT UnInit();
  165. HRESULT AddReqObj(CViperAsyncRequest *pReqObj);
  166. BOOL RemoveReqObj(CViperAsyncRequest *pReqObj, BOOL fForce = FALSE);
  167. void LockQueue();
  168. void UnlockQueue();
  169. private:
  170. CDblLink m_ReqObjList;
  171. DWORD m_dwReqObjs;
  172. DWORD m_fCsInited:1;
  173. DWORD m_fCsQueueInited:1;
  174. DWORD m_fShutdown:1;
  175. DWORD m_fDisabled : 1;
  176. CRITICAL_SECTION m_csLock;
  177. CRITICAL_SECTION m_csQueueLock;
  178. DWORD m_dwQueueMin;
  179. HANDLE m_hWakeUpEvent;
  180. HANDLE m_hThreadAlive;
  181. DWORD m_dwLastAwakened;
  182. DWORD m_dwQueueAlwaysWakeupMin;
  183. void Lock();
  184. void Unlock();
  185. CViperAsyncRequest *GetNext(CDblLink *pViperReq, BOOL fTestForF5Attack);
  186. void WakeUp(BOOL fForce = FALSE);
  187. static DWORD __stdcall WatchThread(VOID *pArg);
  188. };
  189. extern CViperReqManager g_ViperReqMgr;
  190. /*===================================================================
  191. CViperReqManager - Inlines
  192. ===================================================================*/
  193. inline void CViperReqManager::Lock()
  194. {
  195. Assert(m_fCsInited);
  196. EnterCriticalSection(&m_csLock);
  197. }
  198. inline void CViperReqManager::Unlock()
  199. {
  200. LeaveCriticalSection(&m_csLock);
  201. }
  202. inline void CViperReqManager::LockQueue()
  203. {
  204. Assert(m_fCsQueueInited);
  205. EnterCriticalSection(&m_csQueueLock);
  206. }
  207. inline void CViperReqManager::UnlockQueue()
  208. {
  209. LeaveCriticalSection(&m_csQueueLock);
  210. }
  211. inline void CViperReqManager::WakeUp(BOOL fForce /* = FALSE */)
  212. {
  213. // set the wakeup event under any of the three conditions:
  214. // 1) fForce is true (set when shutting down)
  215. // 2) requests queued exceed level that will always force wakeup
  216. // 3) not at the force level of requests, but have some queueing and
  217. // haven't awakened for at least one second
  218. if (fForce
  219. || (m_dwReqObjs >= m_dwQueueAlwaysWakeupMin)
  220. || ((m_dwReqObjs >= m_dwQueueMin) && (GetTickCount()/1000 > m_dwLastAwakened)))
  221. SetEvent(m_hWakeUpEvent);
  222. }
  223. /*===================================================================
  224. COM Helper API
  225. ===================================================================*/
  226. BOOL ViperCoObjectIsaProxy
  227. (
  228. IUnknown *pUnk
  229. );
  230. BOOL ViperCoObjectAggregatesFTM
  231. (
  232. IUnknown *pUnk
  233. );
  234. #endif // VIPERINT