📄 objectexporter.cpp
字号:
// Tidy up... delete [] arrayOTEs; return hr; }//////////////////////////////////////////////////////////////////////////////// ObjectExporter::objectMarshal -- marshal an object's interface for// remoting. The class-ID and interface ID are recorded along with the// other info in the object-table...//HRESULT ObjectExporter::objectMarshal ( REFCLSID rclsid, // class ID IStream* pStm, // stream to marshal into REFIID riid, // interface IID IUnknown* pUnk, // interface-ptr to be marshaled DWORD dwDestContext, // destination context void* pvDestContext, // reserved for future use DWORD mshlflags, // reason for marshaling ObjectTableEntry** ppOTE // resulting table entry ) { // See if this object wants to marshal itself (currently this is // only valid if the object is a StdProxy, since we don't support // custom marshaling)... IMarshal* pMshl; HRESULT hr = pUnk->QueryInterface (IID_IMarshal, (void**) &pMshl); if (SUCCEEDED (hr)) { // Let the object marshal its own representation (for a // StdProxy, this will be a direct OBJREF to the remote // object, not to the proxy)... hr = pMshl->MarshalInterface (pStm, riid, pUnk, dwDestContext, pvDestContext, mshlflags); pMshl->Release (); if (ppOTE) *ppOTE = 0; return hr; } // First, see if we already have an entry for this object. To do // this, we must have the actual IUnknown of the object, so we // must QI for it first... IUnknown* punkActual = 0; hr = pUnk->QueryInterface (IID_IUnknown, (void**) &punkActual); if (FAILED (hr)) return hr; punkActual->Release (); // Now we have the actual IUnknown for the object to be marshaled, // see if it already has an entry in the object table... ObjectTableEntry* pOTE = m_objectTable.objectFindByIUnknown (punkActual); if (! pOTE) { // No existing entry, so make one... pOTE = m_objectTable.objectRegister (pStm, rclsid, (mshlflags & MSHLFLAGS_NOPING) != 0); if (! pOTE) return E_OUTOFMEMORY; S_DEBUG (LOG_OBJ_EXPORTER, "Exporting Object OID=" << pOTE->oid << " IID=" << vxcomGUID2String (riid)); } // Create a new StdMarshaler object, with the OID of the object // being marshaled... pMshl = new VxStdMarshaler (pOTE->oid); if (! pMshl) return E_OUTOFMEMORY; pMshl->AddRef (); // Call IMarshal::MarshalInterface to marshal the object's // interface ptr into the stream... hr = pMshl->MarshalInterface (pStm, riid, pUnk, dwDestContext, pvDestContext, mshlflags); // tidy up and return... if (ppOTE) *ppOTE = pOTE; pMshl->Release (); return hr; }//////////////////////////////////////////////////////////////////////////////ObjectTableEntry* ObjectExporter::objectFindByOid ( OID oid ) { TRACE_CALL; return m_objectTable.objectFindByOid (oid); }//////////////////////////////////////////////////////////////////////////////ObjectTableEntry* ObjectExporter::objectFindByStream ( IStream* pStm ) { TRACE_CALL; return m_objectTable.objectFindByStream (pStm); }//////////////////////////////////////////////////////////////////////////////ObjectTableEntry* ObjectExporter::objectFindByToken ( DWORD dwToken ) { TRACE_CALL; return m_objectTable.objectFindByToken (dwToken); }//////////////////////////////////////////////////////////////////////////////ObjectTableEntry* ObjectExporter::objectFindByIUnknown ( IUnknown* pUnk ) { TRACE_CALL; return m_objectTable.objectFindByIUnknown (pUnk); }//////////////////////////////////////////////////////////////////////////////bool ObjectExporter::objectUnregister (OID oid) { TRACE_CALL; return m_objectTable.objectUnregister (oid); }//////////////////////////////////////////////////////////////////////////////void ObjectExporter::objectUnregisterAll () { TRACE_CALL; // Safeguard against our own destruction... AddRef (); // Iterate over the table, releasing each object-table entry VxObjectTable::iterator i = m_objectTable.begin (); while (i != m_objectTable.end ()) { OID oid = (*i).first; ++i; m_objectTable.objectUnregister (oid); } // Remove the safeguard... Release (); }//////////////////////////////////////////////////////////////////////////////// ObjectExporter::init -- method to initialise an instance of the// Object Exporter class.//HRESULT ObjectExporter::init () { TRACE_CALL; // Marshal the Object Exporter's IRemUnknown interface into the // global object table - this allows its methods to be dispatched // by the normal ORPC mechanism. The marshaled interface pointer // will remain in the table forever... IStream* pStrm=0; HRESULT hr = VxRWMemStream::CreateInstance (0, IID_IStream, (void**) &pStrm); if (FAILED (hr)) return hr; IRemUnknown* punk = static_cast<IRemUnknown*> (this); // Marshal the object exporter's IRemUnknown interface without // PING support, so it never expires... hr = CoMarshalInterface (pStrm, IID_IRemUnknown, punk, MSHCTX_LOCAL, 0, MSHLFLAGS_NOPING); pStrm->Release (); if (SUCCEEDED (hr)) { // Create IRemUnknown IPID using OID of just-marshaled // object... ObjectTableEntry* pOTE = objectFindByStream (pStrm); if (pOTE) { // Synthesise IPID of IRemUnknown... m_ipidRemUnknown = orpcIpidCreate (punk, pOTE->oid); S_DEBUG (LOG_RPC, "IPID of IRemUnknown is " << m_ipidRemUnknown); // Save our own OID... m_oid = pOTE->oid; } else hr = E_UNEXPECTED; } return hr; }////////////////////////////////////////////////////////////////////////////// ObjectExporter::tick -- timeout all exported objects by 'nSecs'// seconds. If any object expires, remove it from the table...//HRESULT ObjectExporter::tick (size_t nSecs) { STL_VECTOR(OID) oidsToDelete; VxCritSec cs (m_mutex); VxObjectTable::iterator i = m_objectTable.begin (); while (i != m_objectTable.end ()) { ObjectTableEntry* ote = (*i).second; if (! ote->noPing) { ote->pingTimeout -= nSecs; if (ote->pingTimeout <= 0) { // Timeout has expired - mark the object for // destruction... oidsToDelete.push_back (ote->oid); S_DEBUG (LOG_OBJ_EXPORTER, "Timeout on object OID=" << ote->oid); } } ++i; } for (size_t n=0; n < oidsToDelete.size (); ++n) { S_DEBUG (LOG_OBJ_EXPORTER, "Deleting object OID=" << oidsToDelete [n] << endl); m_objectTable.objectUnregister (oidsToDelete [n]); } return S_OK; }////////////////////////////////////////////////////////////////////////////// ObjectExporter::oidPing -- reset the timeout on a particular// object, as it has been pinged...//HRESULT ObjectExporter::oidPing (OID oid) { ObjectTableEntry* pOTE = m_objectTable.objectFindByOid (oid); if (pOTE) { pOTE->pingTimeout = VXDCOM_PING_TIMEOUT; return S_OK; } return OR_INVALID_OID; }
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -