VirtualBox

Changeset 75853 in vbox for trunk/src/VBox/HostServices


Ignore:
Timestamp:
Nov 30, 2018 7:26:42 PM (6 years ago)
Author:
vboxsync
Message:

GuestControl,HGCM,VBoxService: Save/restore related optimizations and changes. bugref:9313

Location:
trunk/src/VBox/HostServices
Files:
5 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/HostServices/GuestControl/service.cpp

    r75825 r75853  
    6767#include <VBox/AssertGuest.h>
    6868#include <VBox/VMMDev.h>
     69#include <VBox/vmm/ssm.h>
    6970#include <iprt/assert.h>
    7071#include <iprt/cpp/autores.h>
     
    139140    }
    140141
     142
    141143    /**
    142144     * Retains a reference to the command.
     
    149151        return cRefs;
    150152    }
     153
    151154
    152155    /**
     
    180183    }
    181184
     185
    182186    /**
    183187     * Initializes the command.
     
    269273    }
    270274
     275
     276    /**
     277     * Sets the GUEST_MSG_PEEK_WAIT GUEST_MSG_PEEK_NOWAIT return parameters.
     278     *
     279     * @param   paDstParms  The peek parameter vector.
     280     * @param   cDstParms   The number of peek parameters (at least two).
     281     * @remarks ASSUMES the parameters has been cleared by clientMsgPeek.
     282     */
     283    inline void setPeekReturn(PVBOXHGCMSVCPARM paDstParms, uint32_t cDstParms)
     284    {
     285        Assert(cDstParms >= 2);
     286        if (paDstParms[0].type == VBOX_HGCM_SVC_PARM_32BIT)
     287            paDstParms[0].u.uint32 = mMsgType;
     288        else
     289            paDstParms[0].u.uint64 = mMsgType;
     290        paDstParms[1].u.uint32 = mParmCount;
     291
     292        uint32_t i = RT_MIN(cDstParms, mParmCount + 2);
     293        while (i-- > 2)
     294            switch (mpParms[i - 2].type)
     295            {
     296                case VBOX_HGCM_SVC_PARM_32BIT: paDstParms[i].u.uint32 = ~(uint32_t)sizeof(uint32_t); break;
     297                case VBOX_HGCM_SVC_PARM_64BIT: paDstParms[i].u.uint32 = ~(uint32_t)sizeof(uint64_t); break;
     298                case VBOX_HGCM_SVC_PARM_PTR:   paDstParms[i].u.uint32 = mpParms[i - 2].u.pointer.size; break;
     299            }
     300    }
     301
     302
     303    /** @name Support for old-style (GUEST_MSG_WAIT) operation.
     304     * @{
     305     */
    271306
    272307    /**
     
    421456        return VERR_TOO_MUCH_DATA;
    422457    }
     458
     459    /** @} */
    423460} HostCommand;
    424461typedef std::list< HostCommand *> HostCmdList;
     
    527564            rc = VINF_SUCCESS;
    528565
    529             HostCmdListIter curCmd = mHostCmdList.begin();
    530             if (curCmd != mHostCmdList.end())
     566            HostCmdListIter ItFirstCmd = mHostCmdList.begin();
     567            if (ItFirstCmd != mHostCmdList.end())
    531568            {
    532                 HostCommand *pHostCmd = (*curCmd);
    533                 AssertPtrReturn(pHostCmd, VERR_INVALID_POINTER);
     569                HostCommand *pFirstCmd = (*ItFirstCmd);
     570                AssertPtrReturn(pFirstCmd, VERR_INVALID_POINTER);
    534571
    535572                LogFlowThisFunc(("[Client %RU32] Current host command is %RU32 (CID=%RU32, cParms=%RU32, m_cRefs=%RU32)\n",
    536                                  mID, pHostCmd->mMsgType, pHostCmd->m_idContext, pHostCmd->mParmCount, pHostCmd->m_cRefs));
     573                                 mID, pFirstCmd->mMsgType, pFirstCmd->m_idContext, pFirstCmd->mParmCount, pFirstCmd->m_cRefs));
    537574
    538575                if (mIsPending == GUEST_MSG_PEEK_WAIT)
    539576                {
    540                     HGCMSvcSetU32(&mPendingCon.mParms[0], pHostCmd->mMsgType);
    541                     HGCMSvcSetU32(&mPendingCon.mParms[1], pHostCmd->mParmCount);
    542                     uint32_t i = RT_MIN(mPendingCon.mNumParms, pHostCmd->mParmCount + 2);
    543                     while (i-- > 2)
    544                         switch (pHostCmd->mpParms[i - 2].type)
    545                         {
    546                             case VBOX_HGCM_SVC_PARM_32BIT: mPendingCon.mParms[i].u.uint32 = ~(uint32_t)sizeof(uint32_t); break;
    547                             case VBOX_HGCM_SVC_PARM_64BIT: mPendingCon.mParms[i].u.uint32 = ~(uint32_t)sizeof(uint64_t); break;
    548                             case VBOX_HGCM_SVC_PARM_PTR:   mPendingCon.mParms[i].u.uint32 = pHostCmd->mpParms[i - 2].u.pointer.size; break;
    549                         }
    550 
     577                    pFirstCmd->setPeekReturn(mPendingCon.mParms, mPendingCon.mNumParms);
    551578                    rc = mSvcHelpers->pfnCallComplete(mPendingCon.mHandle, VINF_SUCCESS);
    552579
     
    557584                }
    558585                else if (mIsPending == GUEST_MSG_WAIT)
    559                     rc = OldRun(&mPendingCon, pHostCmd);
     586                    rc = OldRun(&mPendingCon, pFirstCmd);
    560587                else
    561588                    AssertMsgFailed(("mIsPending=%d\n", mIsPending));
     
    654681    {
    655682        Assert(!mHostCmdList.empty());
    656         HostCommand *pHostCmd = *mHostCmdList.begin();
    657         AssertPtr(pHostCmd);
    658         pHostCmd->SaneRelease();
     683        HostCommand *pFirstCmd = *mHostCmdList.begin();
     684        AssertPtr(pFirstCmd);
     685        pFirstCmd->SaneRelease();
    659686        mHostCmdList.pop_front();
    660687
     
    879906    RTLISTANCHOR mHostCmdList;
    880907    /** Map containing all connected clients, key is HGCM client ID. */
    881     ClientStateMap  mClientStateMap;
     908    ClientStateMap  mClientStateMap; /**< @todo Use VBOXHGCMSVCFNTABLE::cbClient for this! */
    882909    /** The master HGCM client ID, UINT32_MAX if none. */
    883910    uint32_t        m_idMasterClient;
     
    909936                                      uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[], uint64_t tsArrival);
    910937    static DECLCALLBACK(int)  svcHostCall(void *pvService, uint32_t u32Function, uint32_t cParms, VBOXHGCMSVCPARM paParms[]);
     938    static DECLCALLBACK(int)  svcSaveState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM);
     939    static DECLCALLBACK(int)  svcLoadState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion);
    911940    static DECLCALLBACK(int)  svcRegisterExtension(void *pvService, PFNHGCMSVCEXT pfnExtension, void *pvExtension);
    912941
     
    11991228     */
    12001229    ASSERT_GUEST_MSG_RETURN(cParms >= 2, ("cParms=%u!\n", cParms), VERR_WRONG_PARAMETER_COUNT);
    1201     for (uint32_t i = 0; i < cParms; i++)
     1230
     1231    uint64_t idRestoreCheck = 0;
     1232    uint32_t i              = 0;
     1233    if (paParms[i].type == VBOX_HGCM_SVC_PARM_64BIT)
     1234    {
     1235        idRestoreCheck = paParms[0].u.uint64;
     1236        paParms[0].u.uint64 = 0;
     1237        i++;
     1238    }
     1239    for (; i < cParms; i++)
    12021240    {
    12031241        ASSERT_GUEST_MSG_RETURN(paParms[i].type == VBOX_HGCM_SVC_PARM_32BIT, ("#%u type=%u\n", i, paParms[i].type),
     
    12111249
    12121250    /*
     1251     * Check restore session ID.
     1252     */
     1253    if (idRestoreCheck != 0)
     1254    {
     1255        uint64_t idRestore = mpHelpers->pfnGetVMMDevSessionId(mpHelpers);
     1256        if (idRestoreCheck != idRestore)
     1257        {
     1258            paParms[0].u.uint32 = idRestore;
     1259            LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_XXXX -> VERR_VM_RESTORED (%#RX64 -> %#RX64)\n",
     1260                         idClient, idRestoreCheck, idRestore));
     1261            return VERR_VM_RESTORED;
     1262        }
     1263        Assert(!mpHelpers->pfnIsCallRestored(hCall));
     1264    }
     1265
     1266    /*
    12131267     * Return information about the first command if one is pending in the list.
    12141268     */
     
    12171271    {
    12181272        HostCommand *pFirstCmd = *itFirstCmd;
    1219         paParms[0].u.uint32 = pFirstCmd->mMsgType;
    1220         paParms[1].u.uint32 = pFirstCmd->mParmCount;
    1221         uint32_t i = RT_MIN(cParms, pFirstCmd->mParmCount + 2);
    1222         while (i-- > 2)
    1223             switch (pFirstCmd->mpParms[i - 2].type)
    1224             {
    1225                 case VBOX_HGCM_SVC_PARM_32BIT: paParms[i].u.uint32 = ~(uint32_t)sizeof(uint32_t); break;
    1226                 case VBOX_HGCM_SVC_PARM_64BIT: paParms[i].u.uint32 = ~(uint32_t)sizeof(uint64_t); break;
    1227                 case VBOX_HGCM_SVC_PARM_PTR:   paParms[i].u.uint32 = pFirstCmd->mpParms[i - 2].u.pointer.size; break;
    1228             }
    1229 
     1273        pFirstCmd->setPeekReturn(paParms, cParms);
    12301274        LogFlowFunc(("[Client %RU32] GUEST_MSG_PEEK_XXXX -> VINF_SUCCESS (idMsg=%u (%s), cParms=%u)\n",
    12311275                     idClient, pFirstCmd->mMsgType, GstCtrlHostFnName((eHostFn)pFirstCmd->mMsgType), pFirstCmd->mParmCount));
     
    21972241
    21982242/**
     2243 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnSaveState}
     2244 */
     2245/*static*/ DECLCALLBACK(int)
     2246GstCtrlService::svcSaveState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM)
     2247{
     2248    RT_NOREF(pvClient);
     2249    AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
     2250    SELF *pThis = reinterpret_cast<SELF *>(pvService);
     2251    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2252
     2253    SSMR3PutU32(pSSM, 1);
     2254    SSMR3PutBool(pSSM, idClient == pThis->m_idMasterClient);
     2255    return SSMR3PutBool(pSSM, pThis->m_fLegacyMode);
     2256}
     2257
     2258
     2259/**
     2260 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnLoadState}
     2261 */
     2262/*static*/ DECLCALLBACK(int)
     2263GstCtrlService::svcLoadState(void *pvService, uint32_t idClient, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion)
     2264{
     2265    RT_NOREF(pvClient);
     2266    AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
     2267    SELF *pThis = reinterpret_cast<SELF *>(pvService);
     2268    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2269
     2270    if (uVersion >= HGCM_SAVED_STATE_VERSION)
     2271    {
     2272        uint32_t uSubVersion;
     2273        int rc = SSMR3GetU32(pSSM, &uSubVersion);
     2274        AssertRCReturn(rc, rc);
     2275        if (uSubVersion != 1)
     2276            return SSMR3SetLoadError(pSSM, VERR_SSM_DATA_UNIT_FORMAT_CHANGED, RT_SRC_POS,
     2277                                     "sub version %u, expected 1\n", uSubVersion);
     2278        bool fLegacyMode;
     2279        rc = SSMR3GetBool(pSSM, &fLegacyMode);
     2280        AssertRCReturn(rc, rc);
     2281        pThis->m_fLegacyMode = fLegacyMode;
     2282
     2283        bool fIsMaster;
     2284        rc = SSMR3GetBool(pSSM, &fIsMaster);
     2285        AssertRCReturn(rc, rc);
     2286        if (fIsMaster)
     2287            pThis->m_idMasterClient = idClient;
     2288        ClientStateMapIter It = pThis->mClientStateMap.find(idClient);
     2289        if (It != pThis->mClientStateMap.end())
     2290            It->second.m_fIsMaster = fIsMaster;
     2291        else
     2292            AssertFailed();
     2293    }
     2294    else
     2295    {
     2296        /*
     2297         * For old saved states we have to guess at who should be the master.
     2298         * Given how HGCMService::CreateAndConnectClient and associates manage
     2299         * and saves the client, the first client connecting will be restored
     2300         * first.  The only time this might go wrong if the there are zombie
     2301         * VBoxService session processes in the restored guest, and I don't
     2302         * we need to care too much about that scenario.
     2303         *
     2304         * Given how HGCM first re-connects the clients before this function
     2305         * gets called, there isn't anything we need to do here it turns out. :-)
     2306         */
     2307    }
     2308    return VINF_SUCCESS;
     2309}
     2310
     2311
     2312/**
    21992313 * @interface_method_impl{VBOXHGCMSVCFNTABLE,pfnRegisterExtension,
    22002314 *  Installs a host callback for notifications of property changes.}
     
    22032317{
    22042318    AssertLogRelReturn(VALID_PTR(pvService), VERR_INVALID_PARAMETER);
    2205     SELF *pSelf = reinterpret_cast<SELF *>(pvService);
    2206     AssertPtrReturn(pSelf, VERR_INVALID_POINTER);
    2207     pSelf->mpfnHostCallback = pfnExtension;
    2208     pSelf->mpvHostData = pvExtension;
     2319    SELF *pThis = reinterpret_cast<SELF *>(pvService);
     2320    AssertPtrReturn(pThis, VERR_INVALID_POINTER);
     2321
     2322    pThis->mpfnHostCallback = pfnExtension;
     2323    pThis->mpvHostData = pvExtension;
    22092324    return VINF_SUCCESS;
    22102325}
     
    22562371                 * because we're a class which can have members for that :-).
    22572372                 */
    2258                 pTable->cbClient = 0;
     2373                pTable->cbClient = 0;  /** @todo this is where ClientState should live, isn't it? */
    22592374
    22602375                /* Register functions. */
    2261                 pTable->pfnUnload             = GstCtrlService::svcUnload;
    2262                 pTable->pfnConnect            = GstCtrlService::svcConnect;
    2263                 pTable->pfnDisconnect         = GstCtrlService::svcDisconnect;
    2264                 pTable->pfnCall               = GstCtrlService::svcCall;
    2265                 pTable->pfnHostCall           = GstCtrlService::svcHostCall;
    2266                 pTable->pfnSaveState          = NULL;  /* The GstCtrlService is stateless, so the normal */
    2267                 pTable->pfnLoadState          = NULL;  /* construction done before restoring suffices */
    2268                 pTable->pfnRegisterExtension  = GstCtrlService::svcRegisterExtension;
     2376                pTable->pfnUnload               = GstCtrlService::svcUnload;
     2377                pTable->pfnConnect              = GstCtrlService::svcConnect;
     2378                pTable->pfnDisconnect           = GstCtrlService::svcDisconnect;
     2379                pTable->pfnCall                 = GstCtrlService::svcCall;
     2380                pTable->pfnHostCall             = GstCtrlService::svcHostCall;
     2381                pTable->pfnSaveState            = GstCtrlService::svcSaveState;
     2382                pTable->pfnLoadState            = GstCtrlService::svcLoadState;
     2383                pTable->pfnRegisterExtension    = GstCtrlService::svcRegisterExtension;
    22692384
    22702385                /* Service specific initialization. */
  • trunk/src/VBox/HostServices/GuestControl/testcase/Makefile.kmk

    r69111 r75853  
    3535        ../service.cpp \
    3636        tstGuestControlSvc.cpp
    37  tstGuestControlSvc_LIBS     = $(LIB_RUNTIME)
     37 tstGuestControlSvc_LIBS     = $(LIB_RUNTIME) $(LIB_VMM)
    3838
    3939$$(tstGuestControlSvc_0_OUTDIR)/tstGuestControlSvc.run: $$(tstGuestControlSvc_1_STAGE_TARGET)
  • trunk/src/VBox/HostServices/SharedClipboard/service.cpp

    r75773 r75853  
    857857} CLIPSAVEDSTATEDATA;
    858858
    859 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
     859static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion)
    860860{
    861861#ifndef UNIT_TEST
     862    RT_NOREF(uVersion);
    862863    LogRel2 (("svcLoadState: u32ClientID = %d\n", u32ClientID));
    863864
     
    931932
    932933#else  /* UNIT_TEST*/
    933     RT_NOREF3(u32ClientID, pvClient, pSSM);
     934    RT_NOREF(u32ClientID, pvClient, pSSM, uVersion);
    934935#endif /* UNIT_TEST */
    935936    return VINF_SUCCESS;
  • trunk/src/VBox/HostServices/SharedFolders/service.cpp

    r75773 r75853  
    242242}
    243243
    244 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
     244static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion)
    245245{
    246246#ifndef UNITTEST  /* Read this as not yet tested */
    247     RT_NOREF1(u32ClientID);
     247    RT_NOREF(u32ClientID, uVersion);
    248248    uint32_t        nrMappings;
    249249    SHFLCLIENTDATA *pClient = (SHFLCLIENTDATA *)pvClient;
     
    395395    Log(("SharedFolders host service: successfully loaded state\n"));
    396396#else
    397     RT_NOREF3(u32ClientID, pvClient, pSSM);
     397    RT_NOREF(u32ClientID, pvClient, pSSM, uVersion);
    398398#endif
    399399    return VINF_SUCCESS;
  • trunk/src/VBox/HostServices/SharedOpenGL/crserver/crservice.cpp

    r75773 r75853  
    199199}
    200200
    201 static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM)
     201static DECLCALLBACK(int) svcLoadState(void *, uint32_t u32ClientID, void *pvClient, PSSMHANDLE pSSM, uint32_t uVersion)
    202202{
     203    RT_NOREF(pvClient, uVersion);
    203204    int rc = VINF_SUCCESS;
    204 
    205     NOREF(pvClient);
    206205
    207206    Log(("SHARED_CROPENGL svcLoadState: u32ClientID = %d\n", u32ClientID));
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