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.

203 lines
4.6 KiB

  1. /////////////////////////////////////////////////////////////////////////////////////
  2. // BroadcastEventService.h : Declaration of the CBroadcastEventService
  3. // Copyright (c) Microsoft Corporation 2001.
  4. #ifndef __BROADCASTEVENTSERVICE_H_
  5. #define __BROADCASTEVENTSERVICE_H_
  6. #pragma once
  7. #include <queue>
  8. #include "w32extend.h"
  9. #include "regexthread.h"
  10. #include <objectwithsiteimplsec.h>
  11. #include "tuner.h"
  12. namespace BDATuningModel {
  13. typedef CComQIPtr<IBroadcastEvent> PQBroadcastEvent;
  14. typedef std::list<DWORD> AdviseList;
  15. typedef std::queue<GUID> EventQ;
  16. class CReflectionThread : public CBaseThread {
  17. public:
  18. typedef enum OP {
  19. RETHREAD_NOREQUEST,
  20. RETHREAD_FIRE,
  21. RETHREAD_EXIT,
  22. } OP;
  23. private:
  24. virtual DWORD ThreadProc(void) {
  25. PQGIT pGIT(CLSID_StdGlobalInterfaceTable, 0, CLSCTX_INPROC_SERVER);
  26. if (!pGIT) {
  27. TRACELM(TRACE_ERROR, "CReflectionThread::ThreadProc() can't create GIT");
  28. return 1;
  29. }
  30. for (;;) {
  31. OP req = GetRequest();
  32. switch (req) {
  33. case RETHREAD_FIRE: {
  34. Fire(pGIT);
  35. break;
  36. } case RETHREAD_EXIT:
  37. goto exit_thread;
  38. };
  39. };
  40. exit_thread:
  41. return 0;
  42. }
  43. OP GetRequest() {
  44. HANDLE h[2];
  45. h[0] = m_EventSend;
  46. h[1] = m_EventTerminate;
  47. for (;;) {
  48. DWORD rc = MsgWaitForMultipleObjectsEx(2, h, INFINITE, QS_ALLEVENTS, 0);
  49. if (rc == WAIT_OBJECT_0) {
  50. m_EventSend.Reset();
  51. return RETHREAD_FIRE;
  52. } else if (rc == WAIT_OBJECT_0 + 1) {
  53. return RETHREAD_EXIT;
  54. } else {
  55. // pump messages so com runs
  56. MSG msg;
  57. while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
  58. TranslateMessage(&msg);
  59. DispatchMessage(&msg);
  60. }
  61. }
  62. }
  63. }
  64. HRESULT Fire(PQGIT& pGIT);
  65. bool GetNextEvent(GUID& g);
  66. void GetAdviseList(AdviseList& l);
  67. PQGIT m_pGIT;
  68. DWORD m_dwCookie;
  69. EventQ m_FiringQ;
  70. CAMEvent m_EventTerminate;
  71. AdviseList m_AdviseList;
  72. public:
  73. CReflectionThread() :
  74. CBaseThread(COINIT_APARTMENTTHREADED),
  75. m_dwCookie(0)
  76. {}
  77. ~CReflectionThread() {
  78. m_EventTerminate.Set();
  79. Close();
  80. }
  81. HRESULT PostFire(GUID& g) {
  82. CAutoLock lock(&m_WorkerLock);
  83. m_FiringQ.push(g);
  84. // signal the worker thread
  85. m_EventSend.Set();
  86. return NOERROR;
  87. }
  88. HRESULT Advise(PUnknown& p, DWORD* pdwCookie);
  89. HRESULT Unadvise(DWORD dwCookie);
  90. }; // class CReflectionThread
  91. /////////////////////////////////////////////////////////////////////////////
  92. // CBroadcastEventService
  93. class ATL_NO_VTABLE CBroadcastEventService :
  94. public CComObjectRootEx<CComMultiThreadModel>,
  95. public CComCoClass<CBroadcastEventService, &CLSID_BroadcastEventService>,
  96. public IObjectWithSiteImplSec<CBroadcastEventService>,
  97. public IBroadcastEvent,
  98. public IConnectionPoint {
  99. public:
  100. CBroadcastEventService() {
  101. m_pRT = new CReflectionThread;
  102. if (!m_pRT->Create()) {
  103. THROWCOM(E_UNEXPECTED);
  104. }
  105. }
  106. virtual ~CBroadcastEventService() {
  107. if (m_pRT) {
  108. delete m_pRT;
  109. m_pRT = NULL;
  110. }
  111. }
  112. REGISTER_NONAUTOMATION_OBJECT_WITH_TM(IDS_REG_TUNEROBJ,
  113. IDS_REG_TUNINGSPACECONTAINER_DESC,
  114. LIBID_TunerLib,
  115. CLSID_BroadcastEventService, tvBoth);
  116. DECLARE_NOT_AGGREGATABLE(CBroadcastEventService)
  117. BEGIN_COM_MAP(CBroadcastEventService)
  118. COM_INTERFACE_ENTRY(IBroadcastEvent)
  119. COM_INTERFACE_ENTRY(IConnectionPoint)
  120. COM_INTERFACE_ENTRY(IObjectWithSite)
  121. END_COM_MAP_WITH_FTM()
  122. public:
  123. // IConnectionPointContainer
  124. // IBroadcastEventService
  125. STDMETHOD(Fire)(/*[in]*/ GUID EventID) {
  126. try {
  127. return m_pRT->PostFire(EventID);
  128. } catch(...) {
  129. return E_UNEXPECTED;
  130. }
  131. }
  132. STDMETHOD(Advise)(LPUNKNOWN pUnk, LPDWORD pdwCookie) {
  133. if (!pUnk || !pdwCookie) {
  134. return E_POINTER;
  135. }
  136. try {
  137. return m_pRT->Advise(PUnknown(pUnk), pdwCookie);
  138. } catch(...) {
  139. return E_UNEXPECTED;
  140. }
  141. }
  142. STDMETHOD(Unadvise)(DWORD dwCookie) {
  143. try {
  144. return m_pRT->Unadvise(dwCookie);
  145. } catch(...) {
  146. return E_UNEXPECTED;
  147. }
  148. }
  149. STDMETHOD(EnumConnections)(IEnumConnections **ppEnum) {
  150. return E_NOTIMPL;
  151. }
  152. STDMETHOD(GetConnectionInterface)(IID* pIID) {
  153. if (!pIID) {
  154. return E_POINTER;
  155. }
  156. try {
  157. memcpy(pIID, &IID_IBroadcastEvent, sizeof(*pIID));
  158. return NOERROR;
  159. } catch(...) {
  160. return E_UNEXPECTED;
  161. }
  162. }
  163. STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer** pContainer) {
  164. return E_NOTIMPL;
  165. }
  166. protected:
  167. CReflectionThread *m_pRT; // <non-shared> worker thread
  168. };
  169. };
  170. #endif //__BROADCASTEVENTSERVICE_H_