VirtualBox

Changeset 30583 in vbox for trunk/src


Ignore:
Timestamp:
Jul 2, 2010 4:39:53 PM (15 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
63308
Message:

Webservice: avoid calling QueryInterface for every object lookup when interface UUIDs can be more easily compared (this avoids constantly creating and deleting temporary stubs in XPCOM)

Location:
trunk/src/VBox/Main/webservice
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/webservice/vboxweb.cpp

    r30577 r30583  
    11681168            }
    11691169
    1170             _pISession = new ManagedObjectRef(*this, g_pcszISession, session);
     1170            _pISession = new ManagedObjectRef(*this, g_pcszISession, session, com::Guid(COM_IIDOF(ISession)));
    11711171
    11721172            if (g_fVerbose)
     
    11971197 * @return The existing ManagedObjectRef that represents the COM object, or NULL if there's none yet.
    11981198 */
    1199 ManagedObjectRef* WebServiceSession::findRefFromPtr(const ComPtr<IUnknown> &pcu)
     1199ManagedObjectRef* WebServiceSession::findRefFromPtr(const IUnknown *pObject)
    12001200{
    12011201    Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread());
    12021202
    1203     IUnknown *p = pcu;
    1204     uintptr_t ulp = (uintptr_t)p;
    1205     ManagedObjectRef *pRef;
     1203    uintptr_t ulp = (uintptr_t)pObject;
    12061204    // WEBDEBUG(("   %s: looking up 0x%lX\n", __FUNCTION__, ulp));
    12071205    ManagedObjectsMapByPtr::iterator it = _pp->_mapManagedObjectsByPtr.find(ulp);
    12081206    if (it != _pp->_mapManagedObjectsByPtr.end())
    12091207    {
    1210         pRef = it->second;
     1208        ManagedObjectRef *pRef = it->second;
    12111209        WSDLT_ID id = pRef->toWSDL();
    12121210        WEBDEBUG(("   %s: found existing ref %s (%s) for COM obj 0x%lX\n", __FUNCTION__, id.c_str(), pRef->getInterfaceName(), ulp));
    1213     }
    1214     else
    1215         pRef = NULL;
    1216     return pRef;
     1211        return pRef;
     1212    }
     1213
     1214    return NULL;
    12171215}
    12181216
     
    12661264}
    12671265
    1268 /**
    1269  *
    1270  */
    1271 void WebServiceSession::DumpRefs()
    1272 {
    1273     WEBDEBUG(("   dumping object refs:\n"));
    1274     ManagedObjectsIteratorById
    1275         iter = _pp->_mapManagedObjectsById.begin(),
    1276         end = _pp->_mapManagedObjectsById.end();
    1277     for (;
    1278         iter != end;
    1279         ++iter)
    1280     {
    1281         ManagedObjectRef *pRef = iter->second;
    1282         uint64_t id = pRef->getID();
    1283         void *p = pRef->getComPtr();
    1284         WEBDEBUG(("     objid %llX: comptr 0x%lX\n", id, p));
    1285     }
    1286 }
    12871266
    12881267/****************************************************************************
     
    13091288 *      instance already exists for a given COM pointer.
    13101289 *
     1290 *  This constructor calls AddRef() on the given COM object, and
     1291 *  the destructor will call Release().
     1292 *
    13111293 *  This does _not_ check whether another instance already
    13121294 *  exists in the hash. This gets called only from the
     
    13201302ManagedObjectRef::ManagedObjectRef(WebServiceSession &session,
    13211303                                   const char *pcszInterface,
    1322                                    const ComPtr<IUnknown> &pc)
     1304                                   IUnknown *pObject,
     1305                                   const com::Guid &guidInterface)
    13231306    : _session(session),
    1324       _pObj(pc),
     1307      _pvObj(pObject),
     1308      _guidInterface(guidInterface),
    13251309      _pcszInterface(pcszInterface)
    13261310{
    1327     ComPtr<IUnknown> pcUnknown(pc);
    1328     _ulp = (uintptr_t)(IUnknown*)pcUnknown;
     1311    Assert(pObject);
     1312    pObject->AddRef();
     1313    _ulp = (uintptr_t)pObject;
    13291314
    13301315    Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread());
     
    13471332/**
    13481333 * Destructor; removes the instance from the global hash of
    1349  * managed objects.
     1334 * managed objects. Calls Release() on the contained COM object.
    13501335 *
    13511336 * Preconditions: Caller must have locked g_pSessionsLockHandle.
     
    13561341    ULONG64 cTotal = --g_cManagedObjects;
    13571342
    1358     WEBDEBUG(("   * %s: deleting MOR for ID %llX (%s); now %lld objects total\n", __FUNCTION__, _id, _pcszInterface, cTotal));
     1343    Assert(_pvObj);
     1344
     1345    uint32_t cRefs = ((IUnknown*)_pvObj)->Release();
     1346    WEBDEBUG(("   * %s: deleting MOR for ID %llX (%s; COM refcount now %RI32); now %lld objects total\n", __FUNCTION__, _id, _pcszInterface, cRefs, cTotal));
    13591347
    13601348    // if we're being destroyed from the session's destructor,
     
    14241412        }
    14251413
    1426         WEBDEBUG(("   %s(): sessid %llX, objid %llX\n", __FUNCTION__, sessid, objid));
    14271414        SessionsMapIterator it = g_mapSessions.find(sessid);
    14281415        if (it == g_mapSessions.end())
     
    15971584            // that it will be implicitly be included in all future requests of this
    15981585            // webservice client
    1599             ManagedObjectRef *pRef = new ManagedObjectRef(*pSession, g_pcszIVirtualBox, g_pVirtualBox);
     1586            ManagedObjectRef *pRef = new ManagedObjectRef(*pSession, g_pcszIVirtualBox, g_pVirtualBox, COM_IIDOF(IVirtualBox));
    16001587            resp->returnval = pRef->toWSDL();
    16011588            WEBDEBUG(("VirtualBox object ref is %s\n", resp->returnval.c_str()));
     
    16721659    return SOAP_OK;
    16731660}
     1661
  • trunk/src/VBox/Main/webservice/vboxweb.h

    r30577 r30583  
    121121                         const char *pcszPassword);
    122122
    123         ManagedObjectRef* findRefFromPtr(const ComPtr<IUnknown> &pcu);
     123        ManagedObjectRef* findRefFromPtr(const IUnknown *pObject);
    124124
    125125        uint64_t getID() const
     
    157157        WebServiceSession           &_session;
    158158
    159         // value:
    160         ComPtr<IUnknown>            _pObj;
     159        void                        *_pvObj;                // COM object
     160        com::Guid                   _guidInterface;         // and the interface for which it was created
     161
    161162        const char                  *_pcszInterface;
    162163
     
    171172        ManagedObjectRef(WebServiceSession &session,
    172173                         const char *pcszInterface,
    173                          const ComPtr<IUnknown> &obj);
     174                         IUnknown *pObject,
     175                         const com::Guid &guidInterface);
    174176        ~ManagedObjectRef();
    175177
     
    179181        }
    180182
    181         ComPtr<IUnknown> getComPtr()
    182         {
    183             return _pObj;
     183        /**
     184         * Returns the contained COM pointer and the UUID of the COM interface
     185         * which it supports.
     186         * @param
     187         * @return
     188         */
     189        const com::Guid& getPtr(void** pp)
     190        {
     191            *pp = _pvObj;
     192            return _guidInterface;
    184193        }
    185194
     
    202211/**
    203212 * Template function that resolves a managed object reference to a COM pointer
    204  * of the template class T. Gets called from tons of generated code in
     213 * of the template class T. Gets called only from tons of generated code in
    205214 * methodmaps.cpp.
    206215 *
     
    236245        if (fNullAllowed && pRef == NULL)
    237246        {
     247            WEBDEBUG(("   %s(): returning NULL object as permitted\n", __FUNCTION__));
    238248            pComPtr.setNull();
    239249            return 0;
    240250        }
    241251
    242         // pRef->getComPtr returns a ComPtr<IUnknown>; by casting it to
    243         // ComPtr<T>, we implicitly do a COM queryInterface() call
    244         if (pComPtr = pRef->getComPtr())
     252        const com::Guid &guidCaller = COM_IIDOF(T);
     253
     254        // pRef->getPtr returns a void*
     255        void *p;
     256        const com::Guid &guidInterface = pRef->getPtr(&p);
     257
     258        if (guidInterface == guidCaller)
     259        {
     260            // same interface: then no QueryInterface needed
     261            WEBDEBUG(("   %s(): returning pointer 0x%lX for original interface %s\n", __FUNCTION__, p, pRef->getInterfaceName()));
     262            pComPtr = (T*)p;            // calls AddRef() once
    245263            return 0;
     264        }
     265
     266        // QueryInterface tests whether p actually supports the templated T interface
     267        T *pT;
     268        ((IUnknown*)p)->QueryInterface(guidCaller, (void**)&pT);      // this adds a reference count
     269        if (pT)
     270        {
     271            // assign to caller's ComPtr<T>; use asOutParam() to avoid adding another reference
     272            WEBDEBUG(("   %s(): returning pointer 0x%lX for queried interface %RTuuid\n", __FUNCTION__, p, guidCaller.raw()));
     273            *(pComPtr.asOutParam()) = pT;
     274            return 0;
     275        }
    246276
    247277        WEBDEBUG(("    Interface not supported for object reference %s, which is of class %s\n", id.c_str(), pRef->getInterfaceName()));
     
    254284
    255285/**
    256  * Template function that creates a new managed object for the given COM
    257  * pointer of the template class T. If a reference already exists for the
    258  * given pointer, then that reference's ID is returned instead.
     286 * Creates a new managed object for the given COM pointer. If a reference already exists
     287 * for the given pointer, then that reference's ID is returned instead.
    259288 *
    260289 * @param idParent managed object reference of calling object; used to extract session ID
     
    265294WSDLT_ID createOrFindRefFromComPtr(const WSDLT_ID &idParent,
    266295                                   const char *pcszInterface,
    267                                    const ComPtr<T> &pc)
     296                                   ComPtr<T> &pc)
    268297{
    269298    // NULL comptr should return NULL MOR
    270299    if (pc.isNull())
    271300    {
    272         WEBDEBUG(("   createOrFindRefFromComPtr(): returning empty MOR for NULL %s pointer\n", pcszInterface));
     301        WEBDEBUG(("   createOrFindRefFromComPtr(): returning empty MOR for NULL COM pointer\n"));
    273302        return "";
    274303    }
     
    278307    if ((pSession = WebServiceSession::findSessionFromRef(idParent)))
    279308    {
    280         // WEBDEBUG(("\n-- found session for %s\n", idParent.c_str()));
    281309        ManagedObjectRef *pRef;
    282         if (    ((pRef = pSession->findRefFromPtr(pc)))
    283              || ((pRef = new ManagedObjectRef(*pSession, pcszInterface, pc)))
     310        ComPtr<IUnknown> pUnknown = pc;       // this calls QueryInterface(IUnknown)
     311        if (    ((pRef = pSession->findRefFromPtr(pUnknown)))
     312             || ((pRef = new ManagedObjectRef(*pSession,
     313                                              pcszInterface,
     314                                              pUnknown,              // IUnknown *pObject
     315                                              COM_IIDOF(T))))
    284316           )
    285317            return pRef->toWSDL();
     
    290322    return "";
    291323}
    292 
Note: See TracChangeset for help on using the changeset viewer.

© 2025 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette