VirtualBox

Changeset 54266 in vbox for trunk


Ignore:
Timestamp:
Feb 18, 2015 3:38:34 PM (10 years ago)
Author:
vboxsync
Message:

Main/webservice: change code to support multiple ISession instances per websession, lots of cleanup and wording changes
Main/idl,doc: matching updates

Location:
trunk
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/doc/manual/en_US/SDKRef.xml

    r52793 r54266  
    12171217
    12181218                <para>Upon logon, the websession manager creates one instance
    1219                 of <xref linkend="IVirtualBox" xreflabel="IVirtualBox" /> and
    1220                 another object of <xref linkend="ISession"
    1221                 xreflabel="ISession" /> representing the web service session.
    1222                 This can be retrieved using <xref
     1219                of <xref linkend="IVirtualBox" xreflabel="IVirtualBox" />,
     1220                which can be used for directly performing calls to its
     1221                methods, or used as a parameter for calling some methods of
     1222                <xref linkend="IWebsessionManager" xreflabel="IWebsessionManager" />.
     1223                Creating Main API session objects is performed using <xref
    12231224                linkend="IWebsessionManager__getSessionObject"
    12241225                xreflabel="IWebsessionManager::getSessionObject()" />.</para>
     
    12261227                <para>(Technically, there is always only one <xref
    12271228                linkend="IVirtualBox" xreflabel="IVirtualBox" /> object, which
    1228                 is shared between all sessions and clients, as it is a COM
     1229                is shared between all websessions and clients, as it is a COM
    12291230                singleton. However, each session receives its own managed
    1230                 object reference to it. The <xref linkend="ISession"
    1231                 xreflabel="ISession" /> object, however, is created and
    1232                 destroyed for each session.)</para>
     1231                object reference to it.)</para>
    12331232              </listitem>
    12341233
     
    15281527name = "Linux"
    15291528mach = vbox.findMachine(name)
    1530 session = mgr.mgr.getSessionObject(vbox)
     1529session = mgr.getSessionObject(vbox)
    15311530progress = mach.launchVMProcess(session, "gui", "")
    15321531progress.waitForCompletion(-1)
     
    15491548        available virtual machines in case of XPCOM), and a mechanism of
    15501549        uniform session creation and closing
    1551         (<computeroutput>mgr.mgr.getSessionObject()</computeroutput>).</para>
     1550        (<computeroutput>mgr.getSessionObject()</computeroutput>).</para>
    15521551
    15531552        <para>In case you want to use the glue layer with a different Python
     
    22922291      xreflabel="ISession" /> interface. Each process which talks to
    22932292      VirtualBox needs its own instance of ISession. In the web service, you
    2294       cannot create such an object, but
    2295       <computeroutput>vboxwebsrv</computeroutput> creates one for you when you
    2296       log on, which you can obtain by calling <xref
     2293      can request the creation of such an object by calling <xref
    22972294      linkend="IWebsessionManager__getSessionObject"
    2298       xreflabel="IWebsessionManager::getSessionObject()" />.</para>
     2295      xreflabel="IWebsessionManager::getSessionObject()" />. More complex
     2296      management tasks might need multiple instances of ISession, and each call
     2297      returns a new one.</para>
    22992298
    23002299      <para>This session object must then be used like a mutex semaphore in
     
    39083907          </itemizedlist></para>
    39093908        </listitem>
     3909
     3910        <listitem>
     3911          <para>The method <xref linkend="IWebsessionManager__getSessionObject"
     3912          xreflabel="IWebsessionManager::getSessionObject()" /> now returns
     3913          a new <xref linkend="ISession" xreflabel="ISession" /> instance for
     3914          every invocation. This puts the behavior in line with other binding
     3915          styles, which never forced the equivalent of establishing another
     3916          connection and logging in again to get another instance.</para>
     3917        </listitem>
    39103918      </itemizedlist>
    39113919    </sect1>
  • trunk/src/VBox/Main/glue/tests/TestVBox.java

    r46478 r54266  
    55
    66/*
    7  * Copyright (C) 2010-2013 Oracle Corporation
     7 * Copyright (C) 2010-2015 Oracle Corporation
    88 *
    99 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1515 * hope that it will be useful, but WITHOUT ANY WARRANTY of any kind.
    1616 */
    17 import org.virtualbox_4_3.*;
     17import org.virtualbox_4_4.*;
    1818import java.util.List;
    1919import java.util.Arrays;
  • trunk/src/VBox/Main/idl/VirtualBox.xidl

    r53906 r54266  
    33<!--
    44
    5     Copyright (C) 2006-2014 Oracle Corporation
     5    Copyright (C) 2006-2015 Oracle Corporation
    66
    77    This file is part of VirtualBox Open Source Edition (OSE), as
     
    1898018980  <interface
    1898118981    name="IWebsessionManager" extends="$unknown"
    18982     uuid="dea1b4c7-2de3-418a-850d-7868617f7733"
     18982    uuid="930c8fea-453a-4a65-aca9-19ed9a872f88"
    1898318983    internal="yes"
    1898418984    wsmap="global"
     
    1900319003    <method name="getSessionObject">
    1900419004      <desc>
    19005         Returns a managed object reference to the internal ISession object that was created
    19006         for this web service session when the client logged on.
     19005        Returns a managed object reference to a new ISession object for every
     19006        call to this method.
    1900719007
    1900819008        <see><link to="ISession"/></see>
     
    1901519015      <desc>
    1901619016        Logs off the client who has previously logged on with <link to="IWebsessionManager::logon" />
    19017         and destroys all resources associated with the session (most importantly, all
    19018         managed objects created in the server while the session was active).
     19017        and destroys all resources associated with the websession (most
     19018        importantly, all managed objects created in the server while the
     19019        websession was active).
    1901919020      </desc>
    1902019021      <param name="refIVirtualBox" type="IVirtualBox" dir="in"/>
  • trunk/src/VBox/Main/webservice/vboxweb.cpp

    r53186 r54266  
    66 *      server, to which clients can connect.
    77 *
    8  * Copyright (C) 2007-2014 Oracle Corporation
     8 * Copyright (C) 2007-2015 Oracle Corporation
    99 *
    1010 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    8686 ****************************************************************************/
    8787
    88 typedef std::map<uint64_t, ManagedObjectRef*>
    89             ManagedObjectsMapById;
    90 typedef std::map<uint64_t, ManagedObjectRef*>::iterator
    91             ManagedObjectsIteratorById;
    92 typedef std::map<uintptr_t, ManagedObjectRef*>
    93             ManagedObjectsMapByPtr;
    94 
    95 typedef std::map<uint64_t, WebServiceSession*>
    96             SessionsMap;
    97 typedef std::map<uint64_t, WebServiceSession*>::iterator
    98             SessionsMapIterator;
    99 
    100 int fntWatchdog(RTTHREAD ThreadSelf, void *pvUser);
     88typedef std::map<uint64_t, ManagedObjectRef*>   ManagedObjectsMapById;
     89typedef ManagedObjectsMapById::iterator         ManagedObjectsIteratorById;
     90typedef std::map<uintptr_t, ManagedObjectRef*>  ManagedObjectsMapByPtr;
     91typedef ManagedObjectsMapByPtr::iterator        ManagedObjectsIteratorByPtr;
     92
     93typedef std::map<uint64_t, WebServiceSession*>  WebsessionsMap;
     94typedef WebsessionsMap::iterator                WebsessionsMapIterator;
     95
     96typedef std::map<RTTHREAD, com::Utf8Str> ThreadsMap;
     97
     98static int fntWatchdog(RTTHREAD ThreadSelf, void *pvUser);
    10199
    102100/****************************************************************************
     
    110108// generated strings in methodmaps.cpp
    111109extern const char       *g_pcszISession,
    112                         *g_pcszIVirtualBox;
     110                        *g_pcszIVirtualBox,
     111                        *g_pcszIVirtualBoxErrorInfo;
    113112
    114113// globals for vboxweb command-line arguments
    115114#define DEFAULT_TIMEOUT_SECS 300
    116115#define DEFAULT_TIMEOUT_SECS_STRING "300"
    117 int                     g_iWatchdogTimeoutSecs = DEFAULT_TIMEOUT_SECS;
    118 int                     g_iWatchdogCheckInterval = 5;
    119 
    120 const char              *g_pcszBindToHost = NULL;       // host; NULL = localhost
    121 unsigned int            g_uBindToPort = 18083;          // port
    122 unsigned int            g_uBacklog = 100;               // backlog = max queue size for requests
     116static int              g_iWatchdogTimeoutSecs = DEFAULT_TIMEOUT_SECS;
     117static int              g_iWatchdogCheckInterval = 5;
     118
     119static const char       *g_pcszBindToHost = NULL;       // host; NULL = localhost
     120static unsigned int     g_uBindToPort = 18083;          // port
     121static unsigned int     g_uBacklog = 100;               // backlog = max queue size for requests
    123122
    124123#ifdef WITH_OPENSSL
    125 bool                    g_fSSL = false;                 // if SSL is enabled
    126 const char              *g_pcszKeyFile = NULL;          // server key file
    127 const char              *g_pcszPassword = NULL;         // password for server key
    128 const char              *g_pcszCACert = NULL;           // file with trusted CA certificates
    129 const char              *g_pcszCAPath = NULL;           // directory with trusted CA certificates
    130 const char              *g_pcszDHFile = NULL;           // DH file name or DH key length in bits, NULL=use RSA
    131 const char              *g_pcszRandFile = NULL;         // file with random data seed
    132 const char              *g_pcszSID = "vboxwebsrv";      // server ID for SSL session cache
     124static bool             g_fSSL = false;                 // if SSL is enabled
     125static const char       *g_pcszKeyFile = NULL;          // server key file
     126static const char       *g_pcszPassword = NULL;         // password for server key
     127static const char       *g_pcszCACert = NULL;           // file with trusted CA certificates
     128static const char       *g_pcszCAPath = NULL;           // directory with trusted CA certificates
     129static const char       *g_pcszDHFile = NULL;           // DH file name or DH key length in bits, NULL=use RSA
     130static const char       *g_pcszRandFile = NULL;         // file with random data seed
     131static const char       *g_pcszSID = "vboxwebsrv";      // server ID for SSL session cache
    133132#endif /* WITH_OPENSSL */
    134133
    135 unsigned int            g_cMaxWorkerThreads = 100;      // max. no. of worker threads
    136 unsigned int            g_cMaxKeepAlive = 100;          // maximum number of soap requests in one connection
    137 
    138 const char              *g_pcszAuthentication = NULL;   // web service authentication
    139 
    140 uint32_t                g_cHistory = 10;                // enable log rotation, 10 files
    141 uint32_t                g_uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file
    142 uint64_t                g_uHistoryFileSize = 100 * _1M; // max 100MB per file
     134static unsigned int     g_cMaxWorkerThreads = 100;      // max. no. of worker threads
     135static unsigned int     g_cMaxKeepAlive = 100;          // maximum number of soap requests in one connection
     136
     137static const char       *g_pcszAuthentication = NULL;   // web service authentication
     138
     139static uint32_t         g_cHistory = 10;                // enable log rotation, 10 files
     140static uint32_t         g_uHistoryFileTime = RT_SEC_1DAY; // max 1 day per file
     141static uint64_t         g_uHistoryFileSize = 100 * _1M; // max 100MB per file
    143142bool                    g_fVerbose = false;             // be verbose
    144143
    145 bool                    g_fDaemonize = false;           // run in background.
     144static bool             g_fDaemonize = false;           // run in background.
    146145
    147146const WSDLT_ID          g_EmptyWSDLID;                  // for NULL MORs
     
    155154// The one global SOAP queue created by main().
    156155class SoapQ;
    157 SoapQ               *g_pSoapQ = NULL;
     156static SoapQ                    *g_pSoapQ = NULL;
    158157
    159158// this mutex protects the auth lib and authentication
    160 util::WriteLockHandle  *g_pAuthLibLockHandle;
     159static util::WriteLockHandle    *g_pAuthLibLockHandle;
    161160
    162161// this mutex protects the global VirtualBox reference below
    163 static util::RWLockHandle *g_pVirtualBoxLockHandle;
    164 
    165 static ComPtr<IVirtualBox> g_pVirtualBox = NULL;
     162static util::RWLockHandle       *g_pVirtualBoxLockHandle;
     163
     164static ComPtr<IVirtualBox>      g_pVirtualBox = NULL;
    166165
    167166// this mutex protects all of the below
    168 util::WriteLockHandle  *g_pSessionsLockHandle;
    169 
    170 SessionsMap         g_mapSessions;
    171 ULONG64             g_iMaxManagedObjectID = 0;
    172 ULONG64             g_cManagedObjects = 0;
     167util::WriteLockHandle           *g_pWebsessionsLockHandle;
     168
     169static WebsessionsMap           g_mapWebsessions;
     170static ULONG64                  g_cManagedObjects = 0;
    173171
    174172// this mutex protects g_mapThreads
    175 util::RWLockHandle  *g_pThreadsLockHandle;
    176 
    177 // this mutex synchronizes logging
    178 util::WriteLockHandle *g_pWebLogLockHandle;
     173static util::RWLockHandle       *g_pThreadsLockHandle;
    179174
    180175// Threads map, so we can quickly map an RTTHREAD struct to a logger prefix
    181 typedef std::map<RTTHREAD, com::Utf8Str> ThreadsMap;
    182 ThreadsMap          g_mapThreads;
     176static ThreadsMap               g_mapThreads;
    183177
    184178/****************************************************************************
     
    218212    };
    219213
    220 void DisplayHelp()
     214static void DisplayHelp()
    221215{
    222216    RTStrmPrintf(g_pStdErr, "\nUsage: vboxwebsrv [options]\n\nSupported options (default values in brackets):\n");
     
    640634                    }
    641635                    {
    642                         // we're messing with sessions, so lock them
    643                         util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    644                         WEBDEBUG(("SVC unavailable: deleting %d sessions\n", g_mapSessions.size()));
    645 
    646                         SessionsMap::iterator it = g_mapSessions.begin(),
    647                                               itEnd = g_mapSessions.end();
     636                        // we're messing with websessions, so lock them
     637                        util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     638                        WEBDEBUG(("SVC unavailable: deleting %d websessions\n", g_mapWebsessions.size()));
     639
     640                        WebsessionsMapIterator it = g_mapWebsessions.begin(),
     641                                               itEnd = g_mapWebsessions.end();
    648642                        while (it != itEnd)
    649643                        {
    650                             WebServiceSession *pSession = it->second;
    651                             WEBDEBUG(("SVC unavailable: Session %llX stale, deleting\n", pSession->getID()));
    652                             delete pSession;
    653                             it = g_mapSessions.begin();
     644                            WebServiceSession *pWebsession = it->second;
     645                            WEBDEBUG(("SVC unavailable: websession %#llx stale, deleting\n", pWebsession->getID()));
     646                            delete pWebsession;
     647                            it = g_mapWebsessions.begin();
    654648                        }
    655649                    }
     
    829823 ****************************************************************************/
    830824
    831 void doQueuesLoop()
     825static void doQueuesLoop()
    832826{
    833827#ifdef WITH_OPENSSL
     
    909903 * SOAP queue worker threads.
    910904 */
    911 int fntQPumper(RTTHREAD ThreadSelf, void *pvUser)
     905static int fntQPumper(RTTHREAD ThreadSelf, void *pvUser)
    912906{
    913907    // store a log prefix for this thread
     
    12021196    g_pAuthLibLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE);
    12031197    g_pVirtualBoxLockHandle = new util::RWLockHandle(util::LOCKCLASS_WEBSERVICE);
    1204     g_pSessionsLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE);
     1198    g_pWebsessionsLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE);
    12051199    g_pThreadsLockHandle = new util::RWLockHandle(util::LOCKCLASS_OBJECTSTATE);
    1206     g_pWebLogLockHandle = new util::WriteLockHandle(util::LOCKCLASS_WEBSERVICE);
    12071200
    12081201    // SOAP queue pumper thread
     
    12661259 * Watchdog thread, runs in the background while the webservice is alive.
    12671260 *
    1268  * This gets started by main() and runs in the background to check all sessions
     1261 * This gets started by main() and runs in the background to check all websessions
    12691262 * for whether they have been no requests in a configurable timeout period. In
    1270  * that case, the session is automatically logged off.
    1271  */
     1263 * that case, the websession is automatically logged off.
     1264 */
     1265/* static */
    12721266int fntWatchdog(RTTHREAD ThreadSelf, void *pvUser)
    12731267{
     
    12871281        time(&tNow);
    12881282
    1289         // we're messing with sessions, so lock them
    1290         util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    1291         WEBDEBUG(("Watchdog: checking %d sessions\n", g_mapSessions.size()));
    1292 
    1293         SessionsMap::iterator it = g_mapSessions.begin(),
    1294                               itEnd = g_mapSessions.end();
     1283        // we're messing with websessions, so lock them
     1284        util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     1285        WEBDEBUG(("Watchdog: checking %d websessions\n", g_mapWebsessions.size()));
     1286
     1287        WebsessionsMapIterator it = g_mapWebsessions.begin(),
     1288                               itEnd = g_mapWebsessions.end();
    12951289        while (it != itEnd)
    12961290        {
    1297             WebServiceSession *pSession = it->second;
    1298             WEBDEBUG(("Watchdog: tNow: %d, session timestamp: %d\n", tNow, pSession->getLastObjectLookup()));
    1299             if (   tNow
    1300                  > pSession->getLastObjectLookup() + g_iWatchdogTimeoutSecs
    1301                )
     1291            WebServiceSession *pWebsession = it->second;
     1292            WEBDEBUG(("Watchdog: tNow: %d, websession timestamp: %d\n", tNow, pWebsession->getLastObjectLookup()));
     1293            if (tNow > pWebsession->getLastObjectLookup() + g_iWatchdogTimeoutSecs)
    13021294            {
    1303                 WEBDEBUG(("Watchdog: Session %llX timed out, deleting\n", pSession->getID()));
    1304                 delete pSession;
    1305                 it = g_mapSessions.begin();
     1295                WEBDEBUG(("Watchdog: websession %#llx timed out, deleting\n", pWebsession->getID()));
     1296                delete pWebsession;
     1297                it = g_mapWebsessions.begin();
    13061298            }
    13071299            else
     
    13381330 * @param ex
    13391331 */
    1340 void RaiseSoapFault(struct soap *soap,
    1341                     const char *pcsz,
    1342                     int extype,
    1343                     void *ex)
     1332static void RaiseSoapFault(struct soap *soap,
     1333                           const char *pcsz,
     1334                           int extype,
     1335                           void *ex)
    13441336{
    13451337    // raise the fault
     
    15151507    info.getVirtualBoxErrorInfo(pVirtualBoxErrorInfo);
    15161508    ex->resultCode = apirc;
    1517     ex->returnval = createOrFindRefFromComPtr(idThis, "IVirtualBoxErrorInfo", pVirtualBoxErrorInfo);
     1509    ex->returnval = createOrFindRefFromComPtr(idThis, g_pcszIVirtualBoxErrorInfo, pVirtualBoxErrorInfo);
    15181510
    15191511    RaiseSoapFault(soap,
     
    15291521 ****************************************************************************/
    15301522
    1531 uint64_t str2ulonglong(const char *pcsz)
    1532 {
    1533     uint64_t u = 0;
    1534     RTStrToUInt64Full(pcsz, 16, &u);
    1535     return u;
    1536 }
    1537 
    1538 /**
    1539  * Splits a managed object reference (in string form, as
    1540  * passed in from a SOAP method call) into two integers for
    1541  * session and object IDs, respectively.
     1523/**
     1524 * Splits a managed object reference (in string form, as passed in from a SOAP
     1525 * method call) into two integers for websession and object IDs, respectively.
    15421526 *
    15431527 * @param id
    1544  * @param sessid
    1545  * @param objid
     1528 * @param pWebsessId
     1529 * @param pObjId
    15461530 * @return
    15471531 */
    1548 bool SplitManagedObjectRef(const WSDLT_ID &id,
    1549                            uint64_t *pSessid,
    1550                            uint64_t *pObjid)
     1532static bool SplitManagedObjectRef(const WSDLT_ID &id,
     1533                                  uint64_t *pWebsessId,
     1534                                  uint64_t *pObjId)
    15511535{
    15521536    // 64-bit numbers in hex have 16 digits; hence
     
    15601544        memcpy(psz, id.c_str(), 34);
    15611545        psz[16] = '\0';
    1562         if (pSessid)
    1563             *pSessid = str2ulonglong(psz);
    1564         if (pObjid)
    1565             *pObjid = str2ulonglong(psz + 17);
     1546        if (pWebsessId)
     1547            RTStrToUInt64Full(psz, 16, pWebsessId);
     1548        if (pObjId)
     1549            RTStrToUInt64Full(psz + 17, 16, pObjId);
    15661550        return true;
    15671551    }
     
    15721556/**
    15731557 * Creates a managed object reference (in string form) from
    1574  * two integers representing a session and object ID, respectively.
     1558 * two integers representing a websession and object ID, respectively.
    15751559 *
    15761560 * @param sz Buffer with at least 34 bytes space to receive MOR string.
    1577  * @param sessid
    1578  * @param objid
     1561 * @param websessId
     1562 * @param objId
    15791563 * @return
    15801564 */
    1581 void MakeManagedObjectRef(char *sz,
    1582                           uint64_t &sessid,
    1583                           uint64_t &objid)
    1584 {
    1585     RTStrFormatNumber(sz, sessid, 16, 16, 0, RTSTR_F_64BIT | RTSTR_F_ZEROPAD);
     1565static void MakeManagedObjectRef(char *sz,
     1566                                 uint64_t websessId,
     1567                                 uint64_t objId)
     1568{
     1569    RTStrFormatNumber(sz, websessId, 16, 16, 0, RTSTR_F_64BIT | RTSTR_F_ZEROPAD);
    15861570    sz[16] = '-';
    1587     RTStrFormatNumber(sz + 17, objid, 16, 16, 0, RTSTR_F_64BIT | RTSTR_F_ZEROPAD);
     1571    RTStrFormatNumber(sz + 17, objId, 16, 16, 0, RTSTR_F_64BIT | RTSTR_F_ZEROPAD);
    15881572}
    15891573
     
    16021586
    16031587/**
    1604  * Constructor for the session object.
    1605  *
    1606  * Preconditions: Caller must have locked g_pSessionsLockHandle.
     1588 * Constructor for the websession object.
     1589 *
     1590 * Preconditions: Caller must have locked g_pWebsessionsLockHandle.
    16071591 *
    16081592 * @param username
     
    16101594 */
    16111595WebServiceSession::WebServiceSession()
    1612     : _fDestructing(false),
    1613       _pISession(NULL),
     1596    : _uNextObjectID(1),        // avoid 0 for no real reason
     1597      _fDestructing(false),
    16141598      _tLastObjectLookup(0)
    16151599{
    16161600    _pp = new WebServiceSessionPrivate;
    1617     _uSessionID = RTRandU64();
    1618 
    1619     // register this session globally
    1620     Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread());
    1621     g_mapSessions[_uSessionID] = this;
     1601    _uWebsessionID = RTRandU64();
     1602
     1603    // register this websession globally
     1604    Assert(g_pWebsessionsLockHandle->isWriteLockOnCurrentThread());
     1605    g_mapWebsessions[_uWebsessionID] = this;
    16221606}
    16231607
     
    16251609 * Destructor. Cleans up and destroys all contained managed object references on the way.
    16261610 *
    1627  * Preconditions: Caller must have locked g_pSessionsLockHandle.
     1611 * Preconditions: Caller must have locked g_pWebsessionsLockHandle.
    16281612 */
    16291613WebServiceSession::~WebServiceSession()
     
    16311615    // delete us from global map first so we can't be found
    16321616    // any more while we're cleaning up
    1633     Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread());
    1634     g_mapSessions.erase(_uSessionID);
     1617    Assert(g_pWebsessionsLockHandle->isWriteLockOnCurrentThread());
     1618    g_mapWebsessions.erase(_uWebsessionID);
    16351619
    16361620    // notify ManagedObjectRef destructor so it won't
     
    16391623    _fDestructing = true;
    16401624
    1641     // if (_pISession)
    1642     // {
    1643     //     delete _pISession;
    1644     //     _pISession = NULL;
    1645     // }
    1646 
    1647     ManagedObjectsMapById::iterator it,
    1648                                     end = _pp->_mapManagedObjectsById.end();
     1625    ManagedObjectsIteratorById it,
     1626                               end = _pp->_mapManagedObjectsById.end();
    16491627    for (it = _pp->_mapManagedObjectsById.begin();
    16501628         it != end;
     
    17711749    lock.release();
    17721750
    1773     if (!rc)
    1774     {
    1775         do
    1776         {
    1777             // now create the ISession object that this webservice session can use
    1778             // (and of which IWebsessionManager::getSessionObject returns a managed object reference)
    1779             ComPtr<ISession> session;
    1780             rc = g_pVirtualBoxClient->COMGETTER(Session)(session.asOutParam());
    1781             if (FAILED(rc))
    1782             {
    1783                 WEBDEBUG(("ERROR: cannot create session object!"));
    1784                 break;
    1785             }
    1786 
    1787             ComPtr<IUnknown> p2 = session;
    1788             _pISession = new ManagedObjectRef(*this,
    1789                                               p2,                               // IUnknown *pobjUnknown
    1790                                               session,                          // void *pobjInterface
    1791                                               com::Guid(COM_IIDOF(ISession)),
    1792                                               g_pcszISession);
    1793 
    1794             if (g_fVerbose)
    1795             {
    1796                 ISession *p = session;
    1797                 WEBDEBUG(("   * %s: created session object with comptr %#p, MOR = %s\n", __FUNCTION__, p, _pISession->getWSDLID().c_str()));
    1798             }
    1799         } while (0);
    1800     }
    1801 
    18021751    return rc;
    18031752}
    18041753
    18051754/**
    1806  *  Look up, in this session, whether a ManagedObjectRef has already been
     1755 *  Look up, in this websession, whether a ManagedObjectRef has already been
    18071756 *  created for the given COM pointer.
    18081757 *
     
    18131762 *  our private hash table, we must search for one too.
    18141763 *
    1815  * Preconditions: Caller must have locked g_pSessionsLockHandle.
     1764 * Preconditions: Caller must have locked g_pWebsessionsLockHandle.
    18161765 *
    18171766 * @param pcu pointer to a COM object.
     
    18201769ManagedObjectRef* WebServiceSession::findRefFromPtr(const IUnknown *pObject)
    18211770{
    1822     Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread());
     1771    Assert(g_pWebsessionsLockHandle->isWriteLockOnCurrentThread());
    18231772
    18241773    uintptr_t ulp = (uintptr_t)pObject;
    18251774    // WEBDEBUG(("   %s: looking up %#lx\n", __FUNCTION__, ulp));
    1826     ManagedObjectsMapByPtr::iterator it = _pp->_mapManagedObjectsByPtr.find(ulp);
     1775    ManagedObjectsIteratorByPtr it = _pp->_mapManagedObjectsByPtr.find(ulp);
    18271776    if (it != _pp->_mapManagedObjectsByPtr.end())
    18281777    {
     
    18361785
    18371786/**
    1838  * Static method which attempts to find the session for which the given managed
    1839  * object reference was created, by splitting the reference into the session and
    1840  * object IDs and then looking up the session object for that session ID.
    1841  *
    1842  * Preconditions: Caller must have locked g_pSessionsLockHandle in read mode.
    1843  *
    1844  * @param id Managed object reference (with combined session and object IDs).
     1787 * Static method which attempts to find the websession for which the given
     1788 * managed object reference was created, by splitting the reference into the
     1789 * websession and object IDs and then looking up the websession object.
     1790 *
     1791 * Preconditions: Caller must have locked g_pWebsessionsLockHandle in read mode.
     1792 *
     1793 * @param id Managed object reference (with combined websession and object IDs).
    18451794 * @return
    18461795 */
    1847 WebServiceSession* WebServiceSession::findSessionFromRef(const WSDLT_ID &id)
    1848 {
    1849     Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread());
    1850 
    1851     WebServiceSession *pSession = NULL;
    1852     uint64_t sessid;
     1796WebServiceSession *WebServiceSession::findWebsessionFromRef(const WSDLT_ID &id)
     1797{
     1798    Assert(g_pWebsessionsLockHandle->isWriteLockOnCurrentThread());
     1799
     1800    WebServiceSession *pWebsession = NULL;
     1801    uint64_t websessId;
    18531802    if (SplitManagedObjectRef(id,
    1854                               &sessid,
     1803                              &websessId,
    18551804                              NULL))
    18561805    {
    1857         SessionsMapIterator it = g_mapSessions.find(sessid);
    1858         if (it != g_mapSessions.end())
    1859             pSession = it->second;
    1860     }
    1861     return pSession;
    1862 }
    1863 
    1864 /**
    1865  *
    1866  */
    1867 const WSDLT_ID& WebServiceSession::getSessionWSDLID() const
    1868 {
    1869     return _pISession->getWSDLID();
    1870 }
    1871 
    1872 /**
    1873  * Touches the webservice session to prevent it from timing out.
    1874  *
    1875  * Each webservice session has an internal timestamp that records
    1876  * the last request made to it from the client that started it.
    1877  * If no request was made within a configurable timeframe, then
    1878  * the client is logged off automatically,
     1806        WebsessionsMapIterator it = g_mapWebsessions.find(websessId);
     1807        if (it != g_mapWebsessions.end())
     1808            pWebsession = it->second;
     1809    }
     1810    return pWebsession;
     1811}
     1812
     1813/**
     1814 * Touches the websession to prevent it from timing out.
     1815 *
     1816 * Each websession has an internal timestamp that records the last request made
     1817 * to it from the client that started it. If no request was made within a
     1818 * configurable timeframe, then the client is logged off automatically,
    18791819 * by calling IWebsessionManager::logoff()
    18801820 */
     
    18931833/**
    18941834 *  Constructor, which assigns a unique ID to this managed object
    1895  *  reference and stores it two global hashes:
    1896  *
    1897  *   a) G_mapManagedObjectsById, which maps ManagedObjectID's to
     1835 *  reference and stores it in two hashes (living in the associated
     1836 *  WebServiceSession object):
     1837 *
     1838 *   a) _mapManagedObjectsById, which maps ManagedObjectID's to
    18981839 *      instances of this class; this hash is then used by the
    18991840 *      findObjectFromRef() template function in vboxweb.h
     
    19031844 *      a managed object ID);
    19041845 *
    1905  *   b) G_mapManagedObjectsByComPtr, which maps COM pointers to
     1846 *   b) _mapManagedObjectsByPtr, which maps COM pointers to
    19061847 *      instances of this class; this hash is used by
    19071848 *      createRefFromObject() to quickly figure out whether an
     
    19221863 *  does perform that check.
    19231864 *
    1924  * Preconditions: Caller must have locked g_pSessionsLockHandle.
    1925  *
    1926  * @param session Session to which the MOR will be added.
     1865 * Preconditions: Caller must have locked g_pWebsessionsLockHandle.
     1866 *
     1867 * @param websession Websession to which the MOR will be added.
    19271868 * @param pobjUnknown Pointer to IUnknown* interface for the COM object; this will be used in the hashes.
    19281869 * @param pobjInterface Pointer to a specific interface for the COM object, described by guidInterface.
     
    19301871 * @param pcszInterface String representation of that interface (e.g. "IMachine") for readability and logging.
    19311872 */
    1932 ManagedObjectRef::ManagedObjectRef(WebServiceSession &session,
     1873ManagedObjectRef::ManagedObjectRef(WebServiceSession &websession,
    19331874                                   IUnknown *pobjUnknown,
    19341875                                   void *pobjInterface,
    19351876                                   const com::Guid &guidInterface,
    19361877                                   const char *pcszInterface)
    1937     : _session(session),
     1878    : _websession(websession),
    19381879      _pobjUnknown(pobjUnknown),
    19391880      _pobjInterface(pobjInterface),
     
    19491890    _ulp = (uintptr_t)pobjUnknown;
    19501891
    1951     Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread());
    1952     _id = ++g_iMaxManagedObjectID;
     1892    Assert(g_pWebsessionsLockHandle->isWriteLockOnCurrentThread());
     1893    _id = websession.createObjectID();
    19531894    // and count globally
    19541895    ULONG64 cTotal = ++g_cManagedObjects;           // raise global count and make a copy for the debug message below
    19551896
    19561897    char sz[34];
    1957     MakeManagedObjectRef(sz, session._uSessionID, _id);
     1898    MakeManagedObjectRef(sz, websession._uWebsessionID, _id);
    19581899    _strID = sz;
    19591900
    1960     session._pp->_mapManagedObjectsById[_id] = this;
    1961     session._pp->_mapManagedObjectsByPtr[_ulp] = this;
    1962 
    1963     session.touch();
    1964 
    1965     WEBDEBUG(("   * %s: MOR created for %s*=%#p (IUnknown*=%#p; COM refcount now %RI32/%RI32), new ID is %llX; now %lld objects total\n",
     1901    websession._pp->_mapManagedObjectsById[_id] = this;
     1902    websession._pp->_mapManagedObjectsByPtr[_ulp] = this;
     1903
     1904    websession.touch();
     1905
     1906    WEBDEBUG(("   * %s: MOR created for %s*=%#p (IUnknown*=%#p; COM refcount now %RI32/%RI32), new ID is %#llx; now %lld objects total\n",
    19661907              __FUNCTION__,
    19671908              pcszInterface,
     
    19781919 * managed objects. Calls Release() on the contained COM object.
    19791920 *
    1980  * Preconditions: Caller must have locked g_pSessionsLockHandle.
     1921 * Preconditions: Caller must have locked g_pWebsessionsLockHandle.
    19811922 */
    19821923ManagedObjectRef::~ManagedObjectRef()
    19831924{
    1984     Assert(g_pSessionsLockHandle->isWriteLockOnCurrentThread());
     1925    Assert(g_pWebsessionsLockHandle->isWriteLockOnCurrentThread());
    19851926    ULONG64 cTotal = --g_cManagedObjects;
    19861927
     
    19921933    uint32_t cRefs2 = ((IUnknown*)_pobjInterface)->Release();
    19931934    uint32_t cRefs1 = _pobjUnknown->Release();
    1994     WEBDEBUG(("   * %s: deleting MOR for ID %llX (%s; COM refcount now %RI32/%RI32); now %lld objects total\n", __FUNCTION__, _id, _pcszInterface, cRefs1, cRefs2, cTotal));
    1995 
    1996     // if we're being destroyed from the session's destructor,
     1935    WEBDEBUG(("   * %s: deleting MOR for ID %#llx (%s; COM refcount now %RI32/%RI32); now %lld objects total\n", __FUNCTION__, _id, _pcszInterface, cRefs1, cRefs2, cTotal));
     1936
     1937    // if we're being destroyed from the websession's destructor,
    19971938    // then that destructor is iterating over the maps, so
    19981939    // don't remove us there! (data integrity + speed)
    1999     if (!_session._fDestructing)
    2000     {
    2001         WEBDEBUG(("   * %s: removing from session maps\n", __FUNCTION__));
    2002         _session._pp->_mapManagedObjectsById.erase(_id);
    2003         if (_session._pp->_mapManagedObjectsByPtr.erase(_ulp) != 1)
    2004             WEBDEBUG(("   WARNING: could not find %llX in _mapManagedObjectsByPtr\n", _ulp));
     1940    if (!_websession._fDestructing)
     1941    {
     1942        WEBDEBUG(("   * %s: removing from websession maps\n", __FUNCTION__));
     1943        _websession._pp->_mapManagedObjectsById.erase(_id);
     1944        if (_websession._pp->_mapManagedObjectsByPtr.erase(_ulp) != 1)
     1945            WEBDEBUG(("   WARNING: could not find %#llx in _mapManagedObjectsByPtr\n", _ulp));
    20051946    }
    20061947}
     
    20131954 * code bloat as we have the actual STL map lookup only in this function.
    20141955 *
    2015  * This also "touches" the timestamp in the session whose ID is encoded
    2016  * in the given integer ID, in order to prevent the session from timing
     1956 * This also "touches" the timestamp in the websession whose ID is encoded
     1957 * in the given integer ID, in order to prevent the websession from timing
    20171958 * out.
    20181959 *
    2019  * Preconditions: Caller must have locked g_mutexSessions.
     1960 * Preconditions: Caller must have locked g_pWebsessionsLockHandle.
    20201961 *
    20211962 * @param strId
     
    20381979        }
    20391980
    2040         uint64_t sessid;
    2041         uint64_t objid;
     1981        uint64_t websessId;
     1982        uint64_t objId;
    20421983        WEBDEBUG(("   %s(): looking up objref %s\n", __FUNCTION__, id.c_str()));
    20431984        if (!SplitManagedObjectRef(id,
    2044                                    &sessid,
    2045                                    &objid))
     1985                                   &websessId,
     1986                                   &objId))
    20461987        {
    20471988            rc = VERR_WEB_INVALID_MANAGED_OBJECT_REFERENCE;
     
    20491990        }
    20501991
    2051         SessionsMapIterator it = g_mapSessions.find(sessid);
    2052         if (it == g_mapSessions.end())
     1992        WebsessionsMapIterator it = g_mapWebsessions.find(websessId);
     1993        if (it == g_mapWebsessions.end())
    20531994        {
    2054             WEBDEBUG(("   %s: cannot find session for objref %s\n", __FUNCTION__, id.c_str()));
     1995            WEBDEBUG(("   %s: cannot find websession for objref %s\n", __FUNCTION__, id.c_str()));
    20551996            rc = VERR_WEB_INVALID_SESSION_ID;
    20561997            break;
    20571998        }
    20581999
    2059         WebServiceSession *pSess = it->second;
    2060         // "touch" session to prevent it from timing out
    2061         pSess->touch();
    2062 
    2063         ManagedObjectsIteratorById iter = pSess->_pp->_mapManagedObjectsById.find(objid);
    2064         if (iter == pSess->_pp->_mapManagedObjectsById.end())
     2000        WebServiceSession *pWebsession = it->second;
     2001        // "touch" websession to prevent it from timing out
     2002        pWebsession->touch();
     2003
     2004        ManagedObjectsIteratorById iter = pWebsession->_pp->_mapManagedObjectsById.find(objId);
     2005        if (iter == pWebsession->_pp->_mapManagedObjectsById.end())
    20652006        {
    20662007            WEBDEBUG(("   %s: cannot find comobj for objref %s\n", __FUNCTION__, id.c_str()));
     
    21042045    {
    21052046        // findRefFromId require the lock
    2106         util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     2047        util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    21072048
    21082049        ManagedObjectRef *pRef;
     
    21392080    {
    21402081        // findRefFromId and the delete call below require the lock
    2141         util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     2082        util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    21422083
    21432084        ManagedObjectRef *pRef;
     
    21742115 *
    21752116 * This returns a managed object reference to the global IVirtualBox object; into this
    2176  * reference a session ID is encoded which remains constant with all managed object
     2117 * reference a websession ID is encoded which remains constant with all managed object
    21772118 * references returned by other methods.
    2178  *
    2179  * This also creates an instance of ISession, which is stored internally with the
    2180  * webservice session and can be retrieved with IWebsessionManager::getSessionObject
    2181  * (__vbox__IWebsessionManager_USCOREgetSessionObject). In order for the
    2182  * VirtualBox web service to do anything useful, one usually needs both a
    2183  * VirtualBox and an ISession object, for which these two methods are designed.
    21842119 *
    21852120 * When the webservice client is done, it should call IWebsessionManager::logoff. This
     
    22102145    {
    22112146        // WebServiceSession constructor tinkers with global MOR map and requires a write lock
    2212         util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    2213 
    2214         // create new session; the constructor stores the new session
     2147        util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     2148
     2149        // create new websession; the constructor stores the new websession
    22152150        // in the global map automatically
    2216         WebServiceSession *pSession = new WebServiceSession();
     2151        WebServiceSession *pWebsession = new WebServiceSession();
    22172152        ComPtr<IVirtualBox> pVirtualBox;
    22182153
    22192154        // authenticate the user
    2220         if (!(pSession->authenticate(req->username.c_str(),
    2221                                      req->password.c_str(),
    2222                                      pVirtualBox.asOutParam())))
     2155        if (!(pWebsession->authenticate(req->username.c_str(),
     2156                                        req->password.c_str(),
     2157                                        pVirtualBox.asOutParam())))
    22232158        {
    2224             // in the new session, create a managed object reference (MOR) for the
    2225             // global VirtualBox object; this encodes the session ID in the MOR so
     2159            // fake up a "root" MOR for this websession
     2160            char sz[34];
     2161            MakeManagedObjectRef(sz, pWebsession->getID(), 0ULL);
     2162            WSDLT_ID id = sz;
     2163
     2164            // in the new websession, create a managed object reference (MOR) for the
     2165            // global VirtualBox object; this encodes the websession ID in the MOR so
    22262166            // that it will be implicitly be included in all future requests of this
    22272167            // webservice client
    2228             ComPtr<IUnknown> p2 = pVirtualBox;
    2229             if (pVirtualBox.isNull() || p2.isNull())
    2230             {
    2231                 rc = E_FAIL;
    2232                 break;
    2233             }
    2234             ManagedObjectRef *pRef = new ManagedObjectRef(*pSession,
    2235                                                           p2,                       // IUnknown *pobjUnknown
    2236                                                           pVirtualBox,              // void *pobjInterface
    2237                                                           COM_IIDOF(IVirtualBox),
    2238                                                           g_pcszIVirtualBox);
    2239             resp->returnval = pRef->getWSDLID();
     2168            resp->returnval = createOrFindRefFromComPtr(id, g_pcszIVirtualBox, pVirtualBox);
    22402169            WEBDEBUG(("VirtualBox object ref is %s\n", resp->returnval.c_str()));
    22412170        }
     
    22512180
    22522181/**
    2253  * Returns the ISession object that was created for the webservice client
    2254  * on logon.
     2182 * Returns a new ISession object every time.
     2183 *
     2184 * No longer connected in any way to logons, one websession can easily
     2185 * handle multiple sessions.
    22552186 */
    22562187int __vbox__IWebsessionManager_USCOREgetSessionObject(
     
    22642195    do
    22652196    {
    2266         // findSessionFromRef needs lock
    2267         util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    2268 
    2269         WebServiceSession* pSession;
    2270         if ((pSession = WebServiceSession::findSessionFromRef(req->refIVirtualBox)))
    2271             resp->returnval = pSession->getSessionWSDLID();
    2272 
     2197        // create a new ISession object
     2198        ComPtr<ISession> pSession;
     2199        rc = g_pVirtualBoxClient->COMGETTER(Session)(pSession.asOutParam());
     2200        if (FAILED(rc))
     2201        {
     2202            WEBDEBUG(("ERROR: cannot create session object!"));
     2203            break;
     2204        }
     2205
     2206        // return its MOR
     2207        resp->returnval = createOrFindRefFromComPtr(req->refIVirtualBox, g_pcszISession, pSession);
     2208        WEBDEBUG(("Session object ref is %s\n", resp->returnval.c_str()));
    22732209    } while (0);
    22742210
     
    22972233    do
    22982234    {
    2299         // findSessionFromRef and the session destructor require the lock
    2300         util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    2301 
    2302         WebServiceSession* pSession;
    2303         if ((pSession = WebServiceSession::findSessionFromRef(req->refIVirtualBox)))
     2235        // findWebsessionFromRef and the websession destructor require the lock
     2236        util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     2237
     2238        WebServiceSession* pWebsession;
     2239        if ((pWebsession = WebServiceSession::findWebsessionFromRef(req->refIVirtualBox)))
    23042240        {
    2305             delete pSession;
     2241            WEBDEBUG(("websession logoff, deleting websession %#llx\n", pWebsession->getID()));
     2242            delete pWebsession;
    23062243                // destructor cleans up
    23072244
    2308             WEBDEBUG(("session destroyed, %d sessions left open\n", g_mapSessions.size()));
     2245            WEBDEBUG(("websession destroyed, %d websessions left open\n", g_mapWebsessions.size()));
    23092246        }
    23102247    } while (0);
  • trunk/src/VBox/Main/webservice/vboxweb.h

    r46478 r54266  
    33 *      header file for "real" web server code.
    44 *
    5  * Copyright (C) 2006-2013 Oracle Corporation
     5 * Copyright (C) 2006-2015 Oracle Corporation
    66 *
    77 * This file is part of VirtualBox Open Source Edition (OSE), as
     
    1414 */
    1515
    16 /****************************************************************************
    17  *
    18  * debug macro
    19  *
    20  ****************************************************************************/
    21 
    22 void WebLog(const char *pszFormat, ...);
    23 
    24 #define WEBDEBUG(a) do { if (g_fVerbose) { WebLog a; } } while (0)
    25 
    2616#ifdef DEBUG
    2717#define LOG_GROUP LOG_GROUP_WEBSERVICE
     
    3525#include <VBox/err.h>
    3626
    37 #include <iprt/stream.h>
     27#include <iprt/asm.h>
    3828
    3929#include <string>
     
    4131/****************************************************************************
    4232 *
     33 * debug macro
     34 *
     35 ****************************************************************************/
     36
     37RT_C_DECLS_BEGIN
     38extern void WebLog(const char *pszFormat, ...);
     39RT_C_DECLS_END
     40
     41#define WEBDEBUG(a) do { if (g_fVerbose) { WebLog a; } } while (0)
     42
     43/****************************************************************************
     44 *
    4345 * typedefs
    4446 *
     
    4648
    4749// type used by gSOAP-generated code
    48 typedef std::string WSDLT_ID;               // combined managed object ref (session ID plus object ID)
     50typedef std::string WSDLT_ID;               // combined managed object ref (websession ID plus object ID)
    4951typedef std::string vbox__uuid;
    5052
     
    5759extern bool g_fVerbose;
    5860
    59 extern PRTSTREAM g_pstrLog;
    60 
    61 extern util::WriteLockHandle  *g_pAuthLibLockHandle;
    62 extern util::WriteLockHandle  *g_pSessionsLockHandle;
     61extern util::WriteLockHandle  *g_pWebsessionsLockHandle;
    6362
    6463extern const WSDLT_ID          g_EmptyWSDLID;
     
    7069 ****************************************************************************/
    7170
    72 void RaiseSoapInvalidObjectFault(struct soap *soap, WSDLT_ID obj);
    73 
    74 void RaiseSoapRuntimeFault(struct soap *soap, const WSDLT_ID &idThis, const char *pcszMethodName, HRESULT apirc, IUnknown *pObj, const com::Guid &iid);
     71extern void RaiseSoapInvalidObjectFault(struct soap *soap, WSDLT_ID obj);
     72
     73extern void RaiseSoapRuntimeFault(struct soap *soap, const WSDLT_ID &idThis, const char *pcszMethodName, HRESULT apirc, IUnknown *pObj, const com::Guid &iid);
    7574
    7675/****************************************************************************
     
    8079 ****************************************************************************/
    8180
    82 std::string ConvertComString(const com::Bstr &bstr);
    83 
    84 std::string ConvertComString(const com::Guid &bstr);
    85 
    86 std::string Base64EncodeByteArray(ComSafeArrayIn(BYTE, aData));
    87 
    88 void Base64DecodeByteArray(struct soap *soap, const std::string& aStr, ComSafeArrayOut(BYTE, aData), const WSDLT_ID &idThis, const char *pszMethodName, IUnknown *pObj, const com::Guid &iid);
     81extern std::string ConvertComString(const com::Bstr &bstr);
     82
     83extern std::string ConvertComString(const com::Guid &bstr);
     84
     85extern std::string Base64EncodeByteArray(ComSafeArrayIn(BYTE, aData));
     86
     87extern void Base64DecodeByteArray(struct soap *soap, const std::string& aStr, ComSafeArrayOut(BYTE, aData), const WSDLT_ID &idThis, const char *pszMethodName, IUnknown *pObj, const com::Guid &iid);
     88
    8989/****************************************************************************
    9090 *
     
    9999 *  An instance of this gets created for every client that logs onto the
    100100 *  webservice (via the special IWebsessionManager::logon() SOAP API) and
    101  *  maintains the managed object references for that session.
     101 *  maintains the managed object references for that websession.
    102102 */
    103103class WebServiceSession
     
    106106
    107107    private:
    108         uint64_t                    _uSessionID;
     108        uint64_t                    _uWebsessionID;
     109        uint64_t                    _uNextObjectID;
    109110        WebServiceSessionPrivate    *_pp;               // opaque data struct (defined in vboxweb.cpp)
    110111        bool                        _fDestructing;
    111 
    112         ManagedObjectRef            *_pISession;
    113112
    114113        time_t                      _tLastObjectLookup;
     
    130129        uint64_t getID() const
    131130        {
    132             return _uSessionID;
    133         }
    134 
    135         const WSDLT_ID& getSessionWSDLID() const;
     131            return _uWebsessionID;
     132        }
     133
     134        uint64_t createObjectID()
     135        {
     136            uint64_t id = ASMAtomicIncU64(&_uNextObjectID);
     137            return id - 1;
     138        }
    136139
    137140        void touch();
     
    142145        }
    143146
    144         static WebServiceSession* findSessionFromRef(const WSDLT_ID &id);
     147        static WebServiceSession* findWebsessionFromRef(const WSDLT_ID &id);
    145148
    146149        void DumpRefs();
     
    149152/**
    150153 *  ManagedObjectRef is used to map COM pointers to object IDs
    151  *  within a session. Such object IDs are 64-bit integers.
     154 *  within a websession. Such object IDs are 64-bit integers.
    152155 *
    153156 *  When a webservice method call is invoked on an object, it
    154157 *  has an opaque string called a "managed object reference". Such
    155  *  a string consists of a session ID combined with an object ID.
     158 *  a string consists of a websession ID combined with an object ID.
    156159 *
    157160 */
     
    159162{
    160163    protected:
    161         // owning session:
    162         WebServiceSession           &_session;
     164        // owning websession:
     165        WebServiceSession           &_websession;
    163166
    164167
     
    179182
    180183    public:
    181         ManagedObjectRef(WebServiceSession &session,
     184        ManagedObjectRef(WebServiceSession &websession,
    182185                         IUnknown *pobjUnknown,
    183186                         void *pobjInterface,
     
    224227                                 ManagedObjectRef **pRef,
    225228                                 bool fNullAllowed);
    226 
    227         static ManagedObjectRef* findFromPtr(ComPtr<IUnknown> pcu);
    228         static ManagedObjectRef* create(const WSDLT_ID &idParent,
    229                                         ComPtr<IUnknown> pcu);
    230 
    231229};
    232230
     
    263261{
    264262    // findRefFromId requires thelock
    265     util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     263    util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    266264
    267265    int rc;
     
    314312
    315313/**
    316  * Creates a new managed object for the given COM pointer. If a reference already exists
    317  * for the given pointer, then that reference's ID is returned instead.
    318  *
    319  * This gets called from tons of generated code in methodmaps.cpp to
    320  * resolve objects *returned* from COM methods (i.e. create MOR strings from COM objects
    321  * which might have been newly created).
    322  *
    323  * @param idParent managed object reference of calling object; used to extract session ID
     314 * Creates a new managed object reference for the given COM pointer. If one
     315 * already exists for the given pointer, then that reference's ID is returned.
     316 *
     317 * This gets called from tons of generated code in methodmaps.cpp to resolve
     318 * objects *returned* from COM methods (i.e. create MOR strings from COM
     319 * objects which might have been newly created).
     320 *
     321 * @param idParent managed object reference of calling object; used to extract
     322 *              websession ID
    324323 * @param pc COM object for which to create a reference
    325324 * @return existing or new managed object reference
     
    328327const WSDLT_ID& createOrFindRefFromComPtr(const WSDLT_ID &idParent,
    329328                                          const char *pcszInterface,
    330                                           ComPtr<T> &pc)
     329                                          const ComPtr<T> &pc)
    331330{
    332331    // NULL comptr should return NULL MOR
     
    337336    }
    338337
    339     util::AutoWriteLock lock(g_pSessionsLockHandle COMMA_LOCKVAL_SRC_POS);
    340     WebServiceSession *pSession;
    341     if ((pSession = WebServiceSession::findSessionFromRef(idParent)))
     338    util::AutoWriteLock lock(g_pWebsessionsLockHandle COMMA_LOCKVAL_SRC_POS);
     339    WebServiceSession *pWebsession;
     340    if ((pWebsession = WebServiceSession::findWebsessionFromRef(idParent)))
    342341    {
    343342        ManagedObjectRef *pRef;
     
    346345        ComPtr<IUnknown> pobjUnknown = pc;
    347346
    348         if (    ((pRef = pSession->findRefFromPtr(pobjUnknown)))
    349              || ((pRef = new ManagedObjectRef(*pSession,
     347        if (    ((pRef = pWebsession->findRefFromPtr(pobjUnknown)))
     348             || ((pRef = new ManagedObjectRef(*pWebsession,
    350349                                              pobjUnknown,          // IUnknown *pobjUnknown
    351350                                              pc,                   // void *pobjInterface
     
    356355    }
    357356
    358     // session has expired, return an empty MOR instead of allocating a
     357    // websession has expired, return an empty MOR instead of allocating a
    359358    // new reference which couldn't be used anyway.
    360359    return g_EmptyWSDLID;
Note: See TracChangeset for help on using the changeset viewer.

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