/////////////////////////////////////////////////////////////////////////// // MsgMgr.h - Provides async enqueuing and dequeuing of message traffic. // // Built as an ATL component with Both threading model. // // // // Jim Fawcett, CSE775 - Distributed Objects, MT1-Q4, Spring 2009 // /////////////////////////////////////////////////////////////////////////// #pragma once #include "resource.h" #include "BlockingQueue.h" #include "threads.h" #include "MessageMgrComp_i.h" #include "../MMFmgrComp/MMFmgrComp_i.h" #if defined(_WIN32_WCE) && !defined(_CE_DCOM) && !defined(_CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA) #error "Single-threaded COM objects are not properly supported on Windows CE platform, such as the Windows Mobile platforms that do not include full DCOM support. Define _CE_ALLOW_SINGLE_THREADED_OBJECTS_IN_MTA to force ATL to support creating single-thread COM object's and allow use of it's single-threaded COM object implementations. The threading model in your rgs file was set to 'Free' as that is the only threading model supported in non DCOM Windows CE platforms." #endif ///////////////////////////////////////////////////////////////////// // Thread Proc for Sender thread class SenderThreadProc : public Thread_Processing { public: SenderThreadProc(BQueue* pSQ, CComQIPtr pMMFcomp) : pSQ_(pSQ), pMMFcomp_(pMMFcomp) {} SenderThreadProc* clone() const { return new SenderThreadProc(*this); } void run() { CoInitializeEx(NULL,COINIT_MULTITHREADED); while(true) { std::wstring msg = pSQ_->deQ(); CComBSTR temp(msg.c_str()); pMMFcomp_->putString(temp); } } private: BQueue* pSQ_; CComQIPtr pMMFcomp_; }; ///////////////////////////////////////////////////////////////////// // Thread Proc for Receiver thread class RecverThreadProc : public Thread_Processing { public: RecverThreadProc(BQueue* pRQ, CComQIPtr pMMFcomp) : pRQ_(pRQ), pMMFcomp_(pMMFcomp) {} RecverThreadProc* clone() const { return new RecverThreadProc(*this); } void run() { CoInitializeEx(NULL,COINIT_MULTITHREADED); while(true) { BSTR temp; pMMFcomp_->getString(&temp); pRQ_->enQ(temp); } } private: BQueue* pRQ_; CComQIPtr pMMFcomp_; }; ///////////////////////////////////////////////////////////////////// // ATL Component class class ATL_NO_VTABLE CMsgMgr : public CComObjectRootEx, public CComCoClass, public IDispatchImpl { public: CMsgMgr() { } DECLARE_REGISTRY_RESOURCEID(IDR_MSGMGR) BEGIN_COM_MAP(CMsgMgr) COM_INTERFACE_ENTRY(IMsgMgr) COM_INTERFACE_ENTRY(IDispatch) END_COM_MAP() DECLARE_PROTECT_FINAL_CONSTRUCT() HRESULT FinalConstruct() { // create instance of inner MMFmgrComp pMMFcomp.CoCreateInstance(CLSID_MMFcomp); // create sending queue and thread pInQ = new BQueue(); Thread* pSender = new Thread(*new SenderThreadProc(pInQ,pMMFcomp)); pSender->start(); // create receiving queue and thread pOutQ = new BQueue(); Thread* pRecver = new Thread(*new RecverThreadProc(pOutQ,pMMFcomp)); pRecver->start(); if(pMMFcomp) return S_OK; return E_FAIL; } void FinalRelease() { delete pSender; delete pRecver; delete pInQ; delete pOutQ; } public: STDMETHOD(putMessage)(BSTR msg); STDMETHOD(getMessage)(BSTR* pMsg); private: BQueue* pInQ; // receive queue BQueue* pOutQ; // send queue CComQIPtr pMMFcomp; // Memory-Mapped file mgr component Thread* pSender; // sender thread Thread* pRecver; // receiver thread // bool debug; }; OBJECT_ENTRY_AUTO(__uuidof(MsgMgr), CMsgMgr)