⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 stdstub.cpp

📁 vxworks操作系统的源代码 供研究学习
💻 CPP
字号:
/* StdStub.cpp - COM/DCOM StdStub class implementation *//*modification history--------------------02f,17dec01,nel  Add include symbol for StdStub.02e,31jul01,dbs  import full T2 changes for stublet refcounts02d,13jul01,dbs  fix up includes02c,20sep00,nel  Add changes made in T2 since branch.02b,28feb00,dbs  add fake stub disp table for IUnknown02a,02aug99,dbs  return correct err code when no stublet01z,27jul99,drm  Returning CLSID from interfaceInfoGet().01y,09jul99,dbs  change to new ObjectExporter naming01x,08jul99,dbs  remove print statements01w,29jun99,dbs  no longer need to unregister StdStub in dtor01v,28jun99,dbs  make Relase() return refs so deletion can be done by OX01u,17jun99,aim  uses new SCM01t,10jun99,dbs  remove op new and delete01s,08jun99,dbs  remove use of mtmap01r,04jun99,dbs  change GuidMap to mtmap01q,03jun99,dbs  no return value from mutex lock01p,02jun99,dbs  inherit from RpcDispatchTable01o,26may99,dbs  fix remote ref-count for IUnknown stublet01n,25may99,dbs  fix stublet refcount for IUnknown stublet01m,24may99,dbs  ask SCM for local object exporter01l,18may99,dbs  change to new marshaling architecture01k,11may99,dbs  fix pure-virtual call problem01j,11may99,dbs  simplify stub remoting architecture01i,07may99,dbs  fix method calls to exporter01h,29apr99,dbs  fix -Wall warnings01g,28apr99,dbs  use COM_MEM_ALLOC for all classes01f,26apr99,aim  added TRACE_CALL01e,26apr99,dbs  remove class-specific debug code01d,26apr99,dbs  add mem-pool to StubInfo class01c,23apr99,dbs  add mem-pool to class01b,22apr99,dbs  tidy up potential leaks01a,20apr99,dbs  created during Grand Renaming*//*  DESCRIPTION:  StdStub -- */#include "StdStub.h"#include "Stublet.h"#include "SCM.h"#include "orpcLib.h"#include "PSFactory.h"/* Include symbol for diab */extern "C" int include_vxdcom_StdStub (void)    {    return 0;    }////////////////////////////////////////////////////////////////////////////// VxStdStub::VxStdStub -- default ctor...//VxStdStub::VxStdStub () : m_pUnkServer (0), m_oid (0)    {    }////////////////////////////////////////////////////////////////////////////// VxStdStub destructor --//VxStdStub::~VxStdStub ()    {    TRACE_CALL;    // Release all the stublets associated with this instance of    // VxStdStub...    VxCritSec cs (m_mutex);    STUBLETMAP::iterator i = m_stublets.begin ();    while (i != m_stublets.end ())	{	VxStublet* pStublet = (*i).second;	if (pStublet)	    delete pStublet;	++i;	}        // Release the server object we are representing    if (m_pUnkServer)        m_pUnkServer->Release ();    }////////////////////////////////////////////////////////////////////////////ULONG VxStdStub::AddRef (ULONG n, REFIPID ipid)    {    TRACE_CALL;    VxCritSec cs (m_mutex);    STUBLETMAP::const_iterator i = m_stublets.find (ipid);    if (i != m_stublets.end ())	{	VxStublet* pStublet = (*i).second;	pStublet->addRefs (n);	}        return n;    }////////////////////////////////////////////////////////////////////////////ULONG VxStdStub::Release (ULONG n, REFIPID ipid)    {    TRACE_CALL;    ULONG nRefs=1;    // Only take action if we have some refs to release...    if (n)	{	VxCritSec cs (m_mutex);    	STUBLETMAP::const_iterator i = m_stublets.find (ipid);	if (i != m_stublets.end ())	    {	    VxStublet* pStublet = (*i).second;	    pStublet->relRefs (n);	    }	// Now add up remote refs, and destroy stub if zero...	nRefs = 0;	for (i = m_stublets.begin (); i != m_stublets.end (); ++i)	    {	    VxStublet* pStublet = (*i).second;	    nRefs += pStublet->refs ();	    }	}        return nRefs;    }////////////////////////////////////////////////////////////////////////////// interfaceAdd -- adds an interface-stub (a 'stublet') for the// given IID on the stubbed object, and adds 'nRefs' remote references// for it. Returns the IPID of the interface if requested.//// As objects typically re-use one of their interfaces as their// IUnknown we must always check the interface-ptr to see if an IPID// for it already exists (IPID values are repeatable, given an OID// value and an interface pointer) - if not we make a new entry.//// Also, there is no interface-stub (stublet) for the IUnknown interface// as the StdStub provides this functionality, so IUnknown is treated// as a special case here.//// Note the this StdStub object keeps one reference to the main// IUnknown of the server object in m_pUnkServer, and each stublet// also keeps one reference to the particular interface it is// representing, so even an object with only one interface will have 2// references to it when being remoted - one by the StdStub and one by// the stublet for its primary interface.//HRESULT VxStdStub::interfaceAdd    (    REFIID      iid,    DWORD       nRefs,    IPID*       pIpidNew    )    {    TRACE_CALL;    HRESULT hr = S_OK;    VxStublet* pStublet=0;    VxStublet* pStubletTmp=0;        // First, we must generate a unique IPID for this interface-ptr...    IUnknown* pOther;    hr = m_pUnkServer->QueryInterface (iid, (void**) &pOther);    if (FAILED (hr))	return hr;        // Using the other interface-ptr, we can create a    // unique IPID value...    IPID ipid = orpcIpidCreate (pOther, m_oid);    // See if we already have a Stublet for this interface - we need    // to look in the per-IPID first, as that is the unique case...        {    VxCritSec cs (m_mutex);    STUBLETMAP::const_iterator i = m_stublets.find (ipid);    if (i != m_stublets.end ())	{	// there is already a stublet for this interface	pStublet = (*i).second;	// If it is a stublet for IUnknown, we need to convert it to	// the new interface ID so it can dispatch methods beyond the	// basic 3 methods of IUnknown. The simplest way of achieving	// this is to erase it and make a new stublet...	if (pStublet->iid () == IID_IUnknown)	    {	    // Save the remote refs we already had on the IUnknown ptr	    // of the server-object...	    pStubletTmp = pStublet;	    nRefs += pStubletTmp->refs ();	    // erase the table-entries	    m_stublets.erase (ipid);	    m_interfaces.erase (IID_IUnknown);	    // make sure we re-create the stublet...	    pStublet = 0;	    }	}    // Now create a new stublet if required...    if (pStublet == 0)	{	// We don't have a stublet, so we must create one. We don't	// release the one reference we got through QI since this will	// be held by the stublet itself, and released when the object	// is destroyed...		VxPSFactory* pPSFactory = VxPSFactory::theInstance ();	pStublet = pPSFactory->CreateStublet (pOther,					      iid,					      ipid);	if (pStublet)	    {	    VxCritSec cs2 (m_mutex);	    m_stublets [ipid] = pStublet;	    }	else	    hr = E_NOINTERFACE;	}    }    // Common operations - add references to the stublet, and make    // sure it has an entry in the per-interface table...    if (pStublet)	{	VxCritSec cs3 (m_mutex);		// make IID-related entry	m_interfaces [iid] = pStublet;	// add new remote-refs	pStublet->addRefs (nRefs);    	// return the IPID value	if (pIpidNew)	    *pIpidNew = pStublet->ipid ();	}    // Get rid of the old stublet (if we had one)...    if (pStubletTmp)	delete pStubletTmp;        // Release the other interface pointer, as the stublet will    // maintain its own reference to the interface...    pOther->Release ();        return hr;    }////////////////////////////////////////////////////////////////////////////// VxStdStub::interfaceInfoGet -- get the interface pointer and// stub-function pointer for the given IPID value from its appropriate// stublet...//HRESULT VxStdStub::interfaceInfoGet    (    REFIID              /*riid*/,    REFIPID		ipid,    ULONG		opnum,    IUnknown**		ppunk,    PFN_ORPC_STUB*	ppfn,    CLSID &		classid    )    {    TRACE_CALL;    VxStublet*		pStublet = 0;    HRESULT		hr = S_OK;    // Make sure its one of our IPIDs --  look for per-stublet info,    // based on IPID...    {        VxCritSec cs (m_mutex);        STUBLETMAP::const_iterator i = m_stublets.find (ipid);    if (i == m_stublets.end ())	hr = RPC_E_INVALID_IPID;    else	pStublet = (*i).second;    }        // Now find the interface ptr    if (pStublet && SUCCEEDED (hr))	hr = pStublet->stubInfoGet (opnum, ppunk, ppfn);    classid = GUID_NULL;    return hr;    }////////////////////////////////////////////////////////////////////////////// VxStdStub::supportsInterface -- determine whether this stub object// supports the given interface (by IID)...//bool VxStdStub::supportsInterface (REFIID riid)    {    TRACE_CALL;    VxCritSec cs (m_mutex);    STUBLETMAP::const_iterator i = m_interfaces.find (riid);    return (i != m_interfaces.end ());    }////////////////////////////////////////////////////////////////////////////// VxStdStub::adopt -- adopt a server-object to be 'exported'. If we// haven't already got its IUnknown then we find it now, and thus hold// one reference to it via m_pUnkServer. This reference will be// released when this StdStub is destroyed...//void VxStdStub::adopt (IUnknown* punk, OID oid)    {    if (! m_pUnkServer)        {        punk->QueryInterface (IID_IUnknown,			  (void**) &m_pUnkServer);        m_oid = oid;        }    }////////////////////////////////////////////////////////////////////////////// Vtbl and stub dispatch-table for IUnknown -- these are never used,// they are just here to fit into the same architecture as all the// other _ps files. PSfactory requires them in order to be able to// return a Facelet for IUnknown...//const PFN_ORPC_STUB IUnknown_vxstub_functbl [] =     {     0,0,0,    };const VXDCOM_STUB_DISPTBL IUnknown_vxstub_disptbl =     {    3,     IUnknown_vxstub_functbl    };const int IUnknown_vxproxy_vtbl=0;VXDCOM_PS_AUTOREGISTER(IUnknown);

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -