windows-nt/Source/XPSP1/NT/multimedia/dshow/vidctl/msvidctl/bcastevent.h
2020-09-26 16:20:57 +08:00

204 lines
4.6 KiB
C++

/////////////////////////////////////////////////////////////////////////////////////
// BroadcastEventService.h : Declaration of the CBroadcastEventService
// Copyright (c) Microsoft Corporation 2001.
#ifndef __BROADCASTEVENTSERVICE_H_
#define __BROADCASTEVENTSERVICE_H_
#pragma once
#include <queue>
#include "w32extend.h"
#include "regexthread.h"
#include <objectwithsiteimplsec.h>
#include "tuner.h"
namespace BDATuningModel {
typedef CComQIPtr<IBroadcastEvent> PQBroadcastEvent;
typedef std::list<DWORD> AdviseList;
typedef std::queue<GUID> EventQ;
class CReflectionThread : public CBaseThread {
public:
typedef enum OP {
RETHREAD_NOREQUEST,
RETHREAD_FIRE,
RETHREAD_EXIT,
} OP;
private:
virtual DWORD ThreadProc(void) {
PQGIT pGIT(CLSID_StdGlobalInterfaceTable, 0, CLSCTX_INPROC_SERVER);
if (!pGIT) {
TRACELM(TRACE_ERROR, "CReflectionThread::ThreadProc() can't create GIT");
return 1;
}
for (;;) {
OP req = GetRequest();
switch (req) {
case RETHREAD_FIRE: {
Fire(pGIT);
break;
} case RETHREAD_EXIT:
goto exit_thread;
};
};
exit_thread:
return 0;
}
OP GetRequest() {
HANDLE h[2];
h[0] = m_EventSend;
h[1] = m_EventTerminate;
for (;;) {
DWORD rc = MsgWaitForMultipleObjectsEx(2, h, INFINITE, QS_ALLEVENTS, 0);
if (rc == WAIT_OBJECT_0) {
m_EventSend.Reset();
return RETHREAD_FIRE;
} else if (rc == WAIT_OBJECT_0 + 1) {
return RETHREAD_EXIT;
} else {
// pump messages so com runs
MSG msg;
while(PeekMessage(&msg, NULL, 0, 0, PM_REMOVE)) {
TranslateMessage(&msg);
DispatchMessage(&msg);
}
}
}
}
HRESULT Fire(PQGIT& pGIT);
bool GetNextEvent(GUID& g);
void GetAdviseList(AdviseList& l);
PQGIT m_pGIT;
DWORD m_dwCookie;
EventQ m_FiringQ;
CAMEvent m_EventTerminate;
AdviseList m_AdviseList;
public:
CReflectionThread() :
CBaseThread(COINIT_APARTMENTTHREADED),
m_dwCookie(0)
{}
~CReflectionThread() {
m_EventTerminate.Set();
Close();
}
HRESULT PostFire(GUID& g) {
CAutoLock lock(&m_WorkerLock);
m_FiringQ.push(g);
// signal the worker thread
m_EventSend.Set();
return NOERROR;
}
HRESULT Advise(PUnknown& p, DWORD* pdwCookie);
HRESULT Unadvise(DWORD dwCookie);
}; // class CReflectionThread
/////////////////////////////////////////////////////////////////////////////
// CBroadcastEventService
class ATL_NO_VTABLE CBroadcastEventService :
public CComObjectRootEx<CComMultiThreadModel>,
public CComCoClass<CBroadcastEventService, &CLSID_BroadcastEventService>,
public IObjectWithSiteImplSec<CBroadcastEventService>,
public IBroadcastEvent,
public IConnectionPoint {
public:
CBroadcastEventService() {
m_pRT = new CReflectionThread;
if (!m_pRT->Create()) {
THROWCOM(E_UNEXPECTED);
}
}
virtual ~CBroadcastEventService() {
if (m_pRT) {
delete m_pRT;
m_pRT = NULL;
}
}
REGISTER_NONAUTOMATION_OBJECT_WITH_TM(IDS_REG_TUNEROBJ,
IDS_REG_TUNINGSPACECONTAINER_DESC,
LIBID_TunerLib,
CLSID_BroadcastEventService, tvBoth);
DECLARE_NOT_AGGREGATABLE(CBroadcastEventService)
BEGIN_COM_MAP(CBroadcastEventService)
COM_INTERFACE_ENTRY(IBroadcastEvent)
COM_INTERFACE_ENTRY(IConnectionPoint)
COM_INTERFACE_ENTRY(IObjectWithSite)
END_COM_MAP_WITH_FTM()
public:
// IConnectionPointContainer
// IBroadcastEventService
STDMETHOD(Fire)(/*[in]*/ GUID EventID) {
try {
return m_pRT->PostFire(EventID);
} catch(...) {
return E_UNEXPECTED;
}
}
STDMETHOD(Advise)(LPUNKNOWN pUnk, LPDWORD pdwCookie) {
if (!pUnk || !pdwCookie) {
return E_POINTER;
}
try {
return m_pRT->Advise(PUnknown(pUnk), pdwCookie);
} catch(...) {
return E_UNEXPECTED;
}
}
STDMETHOD(Unadvise)(DWORD dwCookie) {
try {
return m_pRT->Unadvise(dwCookie);
} catch(...) {
return E_UNEXPECTED;
}
}
STDMETHOD(EnumConnections)(IEnumConnections **ppEnum) {
return E_NOTIMPL;
}
STDMETHOD(GetConnectionInterface)(IID* pIID) {
if (!pIID) {
return E_POINTER;
}
try {
memcpy(pIID, &IID_IBroadcastEvent, sizeof(*pIID));
return NOERROR;
} catch(...) {
return E_UNEXPECTED;
}
}
STDMETHOD(GetConnectionPointContainer)(IConnectionPointContainer** pContainer) {
return E_NOTIMPL;
}
protected:
CReflectionThread *m_pRT; // <non-shared> worker thread
};
};
#endif //__BROADCASTEVENTSERVICE_H_