VirtualBox

Changeset 77587 in vbox for trunk/src/VBox/Main/src-client


Ignore:
Timestamp:
Mar 6, 2019 4:40:18 PM (6 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
129207
Message:

Guest Control/Main: Implemented virtual guest object methods for session status changes to allow guest objects set their internal state accordingly. The guest session's object map now also keeps a (weak) pointer to the guest objects for handling the callbacks.

Location:
trunk/src/VBox/Main/src-client
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Main/src-client/GuestDirectoryImpl.cpp

    r76958 r77587  
    231231
    232232/**
    233  * Called by IGuestSession right before this directory gets
    234  * removed from the public directory list.
    235  */
    236 int GuestDirectory::i_onRemove(void)
    237 {
     233 * @copydoc GuestObject::i_onUnregister
     234 */
     235int GuestDirectory::i_onUnregister(void)
     236{
     237    LogFlowThisFuncEnter();
     238
     239    int vrc = VINF_SUCCESS;
     240
     241    LogFlowFuncLeaveRC(vrc);
     242    return vrc;
     243}
     244
     245/**
     246 * @copydoc GuestObject::i_onSessionStatusChange
     247 */
     248int GuestDirectory::i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus)
     249{
     250    RT_NOREF(enmSessionStatus);
     251
    238252    LogFlowThisFuncEnter();
    239253
  • trunk/src/VBox/Main/src-client/GuestFileImpl.cpp

    r77387 r77587  
    617617
    618618/**
    619  * Called by IGuestSession right before this file gets removed
    620  * from the public file list.
     619 * @copydoc GuestObject::i_onUnregister
    621620 */
    622 int GuestFile::i_onRemove(void)
     621int GuestFile::i_onUnregister(void)
    623622{
    624623    LogFlowThisFuncEnter();
     
    639638        unconst(mEventSource).setNull();
    640639    }
     640
     641    LogFlowFuncLeaveRC(vrc);
     642    return vrc;
     643}
     644
     645/**
     646 * @copydoc GuestObject::i_onSessionStatusChange
     647 */
     648int GuestFile::i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus)
     649{
     650    LogFlowThisFuncEnter();
     651
     652    int vrc = VINF_SUCCESS;
     653
     654    /* If the session now is in a terminated state, set the file status
     655     * to "down", as there is not much else we can do now. */
     656    if (GuestSession::i_isTerminated(enmSessionStatus))
     657        vrc = i_setFileStatus(FileStatus_Down, 0 /* fileRc, ignored */);
    641658
    642659    LogFlowFuncLeaveRC(vrc);
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r77496 r77587  
    281281    LogFlowThisFunc(("mExe=%s, PID=%RU32\n", mData.mProcess.mExecutable.c_str(), mData.mPID));
    282282
    283     /* Terminate process if not already done yet. */
    284     int rcGuest = VINF_SUCCESS;
    285     int vrc = i_terminateProcess(30 * 1000, &rcGuest); /** @todo Make timeouts configurable. */
    286     /* Note: Don't return here yet; first uninit all other stuff in
    287      *       case of failure. */
    288 
    289283    if (mData.mpSessionBaseEnv)
    290284    {
     
    295289    baseUninit();
    296290
    297     LogFlowThisFunc(("Returning rc=%Rrc, rcGuest=%Rrc\n", vrc, rcGuest));
    298     RT_NOREF_PV(vrc);
     291    LogFlowFuncLeave();
    299292}
    300293
     
    818811
    819812/**
    820  * Called by IGuestSession right before this process gets
    821  * removed from the public process list.
     813 * @copydoc GuestObject::i_onUnregister
    822814 */
    823 int GuestProcess::i_onRemove(void)
     815int GuestProcess::i_onUnregister(void)
    824816{
    825817    LogFlowThisFuncEnter();
     
    839831        mLocalListener.setNull();
    840832        unconst(mEventSource).setNull();
     833    }
     834
     835    LogFlowFuncLeaveRC(vrc);
     836    return vrc;
     837}
     838
     839/**
     840 * @copydoc GuestObject::i_onSessionStatusChange
     841 */
     842int GuestProcess::i_onSessionStatusChange(GuestSessionStatus_T enmSessionStatus)
     843{
     844    LogFlowThisFuncEnter();
     845
     846    int vrc = VINF_SUCCESS;
     847
     848    /* If the session now is in a terminated state, set the process status
     849     * to "down", as there is not much else we can do now. */
     850    if (GuestSession::i_isTerminated(enmSessionStatus))
     851    {
     852        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     853
     854        vrc = i_setProcessStatus(ProcessStatus_Down, 0 /* rc, ignored */);
    841855    }
    842856
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r77583 r77587  
    227227     * objects (like files, directories, ...) which are bound to this session.
    228228     */
    229     int rc = i_objectRegister(SESSIONOBJECTTYPE_SESSION, &mData.mObjectID);
     229    int rc = i_objectRegister(NULL /* pObject */, SESSIONOBJECTTYPE_SESSION, &mData.mObjectID);
    230230    if (RT_SUCCESS(rc))
    231231    {
     
    306306    LogFlowThisFuncEnter();
    307307
     308    /* Call i_onRemove to take care of the object cleanups. */
     309    i_onRemove();
     310
    308311    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    309 
    310     LogFlowThisFunc(("Closing directories (%zu total)\n",
    311                      mData.mDirectories.size()));
    312     for (SessionDirectories::iterator itDirs = mData.mDirectories.begin();
    313          itDirs != mData.mDirectories.end(); ++itDirs)
    314     {
    315         itDirs->second->i_onRemove();
    316         itDirs->second->uninit();
    317     }
    318     mData.mDirectories.clear();
    319 
    320     LogFlowThisFunc(("Closing files (%zu total)\n",
    321                      mData.mFiles.size()));
    322     for (SessionFiles::iterator itFiles = mData.mFiles.begin();
    323          itFiles != mData.mFiles.end(); ++itFiles)
    324     {
    325         itFiles->second->i_onRemove();
    326         itFiles->second->uninit();
    327     }
    328     mData.mFiles.clear();
    329 
    330     LogFlowThisFunc(("Closing processes (%zu total)\n",
    331                      mData.mProcesses.size()));
    332     for (SessionProcesses::iterator itProcs = mData.mProcesses.begin();
    333          itProcs != mData.mProcesses.end(); ++itProcs)
    334     {
    335         itProcs->second->i_onRemove();
    336         itProcs->second->uninit();
    337     }
    338     mData.mProcesses.clear();
    339312
    340313    /* Unregister the session's object ID. */
    341314    i_objectUnregister(mData.mObjectID);
    342315
     316    Assert(mData.mObjects.size () == 0);
    343317    mData.mObjects.clear();
    344318
     
    10341008                 idObject, mData.mSession.mID, mData.mDirectories.size()));
    10351009
    1036     rc = pDirConsumed->i_onRemove();
     1010    rc = pDirConsumed->i_onUnregister();
    10371011    AssertRCReturn(rc, rc);
    10381012
     
    11611135    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    11621136
    1163     /* Register a new object ID. */
    1164     uint32_t idObject;
    1165     int rc = i_objectRegister(SESSIONOBJECTTYPE_DIRECTORY, &idObject);
    1166     if (RT_FAILURE(rc))
    1167         return rc;
    1168 
    11691137    /* Create the directory object. */
    11701138    HRESULT hr = pDirectory.createObject();
    11711139    if (FAILED(hr))
    11721140        return VERR_COM_UNEXPECTED;
     1141
     1142    /* Register a new object ID. */
     1143    uint32_t idObject;
     1144    int rc = i_objectRegister(pDirectory, SESSIONOBJECTTYPE_DIRECTORY, &idObject);
     1145    if (RT_FAILURE(rc))
     1146    {
     1147        pDirectory.setNull();
     1148        return rc;
     1149    }
    11731150
    11741151    Console *pConsole = mParent->i_getConsole();
     
    14331410                 pFileConsumed->getObjectID(), mData.mSession.mID, mData.mFiles.size()));
    14341411
    1435     rc = pFileConsumed->i_onRemove();
     1412    rc = pFileConsumed->i_onUnregister();
    14361413    AssertRCReturn(rc, rc);
    14371414
     
    15191496    }
    15201497
    1521     /* Register a new object ID. */
    1522     uint32_t idObject;
    1523     int rc = i_objectRegister(SESSIONOBJECTTYPE_FILE, &idObject);
    1524     if (RT_FAILURE(rc))
    1525         return rc;
    1526 
    15271498    /* Create the directory object. */
    15281499    HRESULT hr = pFile.createObject();
    15291500    if (FAILED(hr))
    15301501        return VERR_COM_UNEXPECTED;
     1502
     1503    /* Register a new object ID. */
     1504    uint32_t idObject;
     1505    int rc = i_objectRegister(pFile, SESSIONOBJECTTYPE_FILE, &idObject);
     1506    if (RT_FAILURE(rc))
     1507    {
     1508        pFile.setNull();
     1509        return rc;
     1510    }
    15311511
    15321512    Console *pConsole = mParent->i_getConsole();
     
    17601740
    17611741/**
    1762  * Returns whether the session is in a terminated state or not.
     1742 * Returns whether a session status implies a terminated state or not.
    17631743 *
    1764  * @returns \c true if in a terminated state, or \c false if not.
     1744 * @returns \c true if it's a terminated state, or \c false if not.
    17651745 */
    1766 bool GuestSession::i_isTerminated(void) const
    1767 {
    1768     switch (mData.mStatus)
     1746/* static */
     1747bool GuestSession::i_isTerminated(GuestSessionStatus_T enmStatus)
     1748{
     1749    switch (enmStatus)
    17691750    {
    17701751        case GuestSessionStatus_Terminated:
     
    17871768
    17881769/**
     1770 * Returns whether the session is in a terminated state or not.
     1771 *
     1772 * @returns \c true if in a terminated state, or \c false if not.
     1773 */
     1774bool GuestSession::i_isTerminated(void) const
     1775{
     1776    return GuestSession::i_isTerminated(mData.mStatus);
     1777}
     1778
     1779/**
    17891780 * Called by IGuest right before this session gets removed from
    17901781 * the public session list.
     
    17961787    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    17971788
    1798     int vrc = VINF_SUCCESS;
     1789    int vrc = i_objectsUnregister();
    17991790
    18001791    /*
     
    20872078 * @retval  VERR_GSTCTL_MAX_OBJECTS_REACHED if the maximum of concurrent objects
    20882079 *          is reached.
     2080 * @param   pObject     Guest object to register (weak pointer). Optional.
    20892081 * @param   enmType     Session object type to register.
    2090  * @param   pidObject   Where to return the object ID on success.
     2082 * @param   pidObject   Where to return the object ID on success. Optional.
    20912083 */
    2092 int GuestSession::i_objectRegister(SESSIONOBJECTTYPE enmType, uint32_t *pidObject)
    2093 {
     2084int GuestSession::i_objectRegister(GuestObject *pObject, SESSIONOBJECTTYPE enmType, uint32_t *pidObject)
     2085{
     2086    /* pObject can be NULL. */
     2087    /* pidObject is optional. */
     2088
    20942089    /*
    20952090     * Pick a random bit as starting point.  If it's in use, search forward
     
    21212116    try
    21222117    {
     2118        mData.mObjects[idObject].pObject = pObject; /* Can be NULL. */
    21232119        mData.mObjects[idObject].enmType = enmType;
    21242120        mData.mObjects[idObject].msBirth = RTTimeMilliTS();
     
    21302126    }
    21312127
    2132     alock.release();
    2133 
    2134     *pidObject = idObject;
     2128    if (pidObject)
     2129        *pidObject = idObject;
     2130
    21352131    return VINF_SUCCESS;
    21362132}
    21372133
    21382134/**
    2139  * Unregisters an object from a session.
     2135 * Unregisters an object from the session objects list.
    21402136 *
    21412137 * @retval  VINF_SUCCESS on success.
     
    21552151
    21562152    return rc;
     2153}
     2154
     2155/**
     2156 * Unregisters all objects from the session list.
     2157 *
     2158 * @returns VBox status code.
     2159 */
     2160int GuestSession::i_objectsUnregister(void)
     2161{
     2162    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     2163
     2164    LogFlowThisFunc(("Unregistering directories (%zu total)\n", mData.mDirectories.size()));
     2165
     2166    SessionDirectories::iterator itDirs;
     2167    while ((itDirs = mData.mDirectories.begin()) != mData.mDirectories.end())
     2168    {
     2169        alock.release();
     2170        i_directoryUnregister(itDirs->second);
     2171        alock.acquire();
     2172    }
     2173
     2174    Assert(mData.mDirectories.size() == 0);
     2175    mData.mDirectories.clear();
     2176
     2177    LogFlowThisFunc(("Unregistering files (%zu total)\n", mData.mFiles.size()));
     2178
     2179    SessionFiles::iterator itFiles;
     2180    while ((itFiles = mData.mFiles.begin()) != mData.mFiles.end())
     2181    {
     2182        alock.release();
     2183        i_fileUnregister(itFiles->second);
     2184        alock.acquire();
     2185    }
     2186
     2187    Assert(mData.mFiles.size() == 0);
     2188    mData.mFiles.clear();
     2189
     2190    LogFlowThisFunc(("Unregistering processes (%zu total)\n", mData.mProcesses.size()));
     2191
     2192    SessionProcesses::iterator itProcs;
     2193    while ((itProcs = mData.mProcesses.begin()) != mData.mProcesses.end())
     2194    {
     2195        alock.release();
     2196        i_processUnregister(itProcs->second);
     2197        alock.acquire();
     2198    }
     2199
     2200    Assert(mData.mProcesses.size() == 0);
     2201    mData.mProcesses.clear();
     2202
     2203    return VINF_SUCCESS;
     2204}
     2205
     2206/**
     2207 * Notifies all registered objects about a session status change.
     2208 *
     2209 * @returns VBox status code.
     2210 * @param   enmSessionStatus    Session status to notify objects about.
     2211 */
     2212int GuestSession::i_objectsNotifyAboutStatusChange(GuestSessionStatus_T enmSessionStatus)
     2213{
     2214    LogFlowThisFunc(("enmSessionStatus=%RU32\n", enmSessionStatus));
     2215
     2216    int vrc = VINF_SUCCESS;
     2217
     2218    SessionObjects::iterator itObjs = mData.mObjects.begin();
     2219    while (itObjs != mData.mObjects.end())
     2220    {
     2221        GuestObject *pObj = itObjs->second.pObject;
     2222        if (pObj) /* pObject can be NULL (weak pointer). */
     2223        {
     2224            int vrc2 = pObj->i_onSessionStatusChange(enmSessionStatus);
     2225            if (RT_SUCCESS(vrc))
     2226                vrc = vrc2;
     2227
     2228            /* If the session got terminated, make sure to cancel all wait events for
     2229             * the current object. */
     2230            if (i_isTerminated())
     2231                pObj->cancelWaitEvents();
     2232        }
     2233
     2234        ++itObjs;
     2235    }
     2236
     2237    LogFlowFuncLeaveRC(vrc);
     2238    return vrc;
    21572239}
    21582240
     
    23332415                 idObject, mData.mSession.mID, uPID, mData.mProcesses.size()));
    23342416
    2335     rc = pProcess->i_onRemove();
     2417    rc = pProcess->i_onUnregister();
    23362418    AssertRCReturn(rc, rc);
    23372419
     
    24142496    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    24152497
    2416     /* Register a new object ID. */
    2417     uint32_t idObject;
    2418     int rc = i_objectRegister(SESSIONOBJECTTYPE_PROCESS, &idObject);
    2419     if (RT_FAILURE(rc))
    2420         return rc;
    2421 
    24222498    /* Create the process object. */
    24232499    HRESULT hr = pProcess.createObject();
    24242500    if (FAILED(hr))
    24252501        return VERR_COM_UNEXPECTED;
     2502
     2503    /* Register a new object ID. */
     2504    uint32_t idObject;
     2505    int rc = i_objectRegister(pProcess, SESSIONOBJECTTYPE_PROCESS, &idObject);
     2506    if (RT_FAILURE(rc))
     2507    {
     2508        pProcess.setNull();
     2509        return rc;
     2510    }
    24262511
    24272512    rc = pProcess->init(mParent->i_getConsole() /* Console */, this /* Session */, idObject,
     
    25512636        AssertMsg(RT_SUCCESS(sessionRc), ("Guest rc must not be an error (%Rrc)\n", sessionRc));
    25522637
     2638    int vrc = VINF_SUCCESS;
     2639
    25532640    if (mData.mStatus != sessionStatus)
    25542641    {
    25552642        mData.mStatus = sessionStatus;
    25562643        mData.mRC     = sessionRc;
     2644
     2645        /* Make sure to notify all underlying objects first. */
     2646        vrc = i_objectsNotifyAboutStatusChange(sessionStatus);
    25572647
    25582648        ComObjPtr<VirtualBoxErrorInfo> errorInfo;
     
    25682658    }
    25692659
    2570     return VINF_SUCCESS;
     2660    LogFlowFuncLeaveRC(vrc);
     2661    return vrc;
    25712662}
    25722663
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