VirtualBox

Changeset 49440 in vbox for trunk/src/VBox/Main


Ignore:
Timestamp:
Nov 11, 2013 3:44:53 PM (11 years ago)
Author:
vboxsync
Message:

Main/GuestCtrl: Bugfixes:

  • Hold lock while registering wait event in GuestProcess::waitFor()
  • Fixes for GuestProcess::waitFlagsToResultEx()
  • Use public wait events for internal GuestFile methods
  • Remove wait event from all other event groups when signaled
Location:
trunk/src/VBox/Main/src-client
Files:
4 edited

Legend:

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

    r49350 r49440  
    907907    *puContextID = uNewContextID;
    908908
     909#if 0
    909910    LogFlowThisFunc(("mNextContextID=%RU32, uSessionID=%RU32, uObjectID=%RU32, uCount=%RU32, uNewContextID=%RU32\n",
    910911                     mNextContextID, uSessionID, uObjectID, uCount, uNewContextID));
     912#endif
    911913    return VINF_SUCCESS;
    912914}
     
    937939            GuestWaitEvent *pEvent = new GuestWaitEvent(uContextID, lstEvents);
    938940            AssertPtr(pEvent);
     941
     942            LogFlowThisFunc(("New event=%p, CID=%RU32\n", pEvent, uContextID));
    939943
    940944            /* Insert event into matching event group. This is for faster per-group
     
    975979    if (RT_SUCCESS(rc))
    976980    {
    977         GuestEventGroup::iterator itGroups = mWaitEventGroups.find(aType);
    978         if (itGroups != mWaitEventGroups.end())
    979         {
    980             for (GuestWaitEvents::iterator itEvents = itGroups->second.begin();
    981                  itEvents != itGroups->second.end(); itEvents++)
     981        GuestEventGroup::iterator itGroup = mWaitEventGroups.find(aType);
     982        if (itGroup != mWaitEventGroups.end())
     983        {
     984            GuestWaitEvents::iterator itEvents = itGroup->second.begin();
     985            while (itEvents != itGroup->second.end())
    982986            {
    983987#ifdef DEBUG
    984                 LogFlowThisFunc(("Signalling event=%p, type=%ld (CID %RU32: Sesion=%RU32, Object=%RU32, Count=%RU32) ...\n",
     988                LogFlowThisFunc(("Signalling event=%p, type=%ld (CID %RU32: Session=%RU32, Object=%RU32, Count=%RU32) ...\n",
    985989                                 itEvents->second, aType, itEvents->first,
    986990                                 VBOX_GUESTCTRL_CONTEXTID_GET_SESSION(itEvents->first),
     
    993997                if (RT_SUCCESS(rc))
    994998                    rc = rc2;
     999
     1000                if (RT_SUCCESS(rc2))
     1001                {
     1002                    /* Remove the event from all other event groups (except the
     1003                     * original one!) because it was signalled. */
     1004                    AssertPtr(itEvents->second);
     1005                    const GuestEventTypes evTypes = itEvents->second->Types();
     1006                    for (GuestEventTypes::const_iterator itType = evTypes.begin();
     1007                         itType != evTypes.end(); itType++)
     1008                    {
     1009                        if ((*itType) != aType) /* Only remove all other groups. */
     1010                        {
     1011                            /* Get current event group. */
     1012                            GuestEventGroup::iterator evGroup = mWaitEventGroups.find((*itType));
     1013                            Assert(evGroup != mWaitEventGroups.end());
     1014
     1015                            /* Lookup event in event group. */
     1016                            GuestWaitEvents::iterator evEvent = evGroup->second.find(itEvents->first /* Context ID */);
     1017                            Assert(evEvent != evGroup->second.end());
     1018
     1019                            LogFlowThisFunc(("Removing event=%p (type %ld)\n", evEvent->second, (*itType)));
     1020                            evGroup->second.erase(evEvent);
     1021
     1022                            LogFlowThisFunc(("%zu events for type=%ld left\n",
     1023                                             evGroup->second.size(), aType));
     1024                        }
     1025                    }
     1026
     1027                    /* Remove the event from the passed-in event group. */
     1028                    itGroup->second.erase(itEvents++);
     1029                }
     1030                else
     1031                    itEvents++;
    9951032#ifdef DEBUG
    9961033                cEvents++;
     
    10521089    if (RT_SUCCESS(rc))
    10531090    {
     1091        LogFlowThisFunc(("pEvent=%p\n", pEvent));
     1092
    10541093        const GuestEventTypes lstTypes = pEvent->Types();
    10551094        for (GuestEventTypes::const_iterator itEvents = lstTypes.begin();
     
    10621101                if (itCurEvent->second == pEvent)
    10631102                {
    1064                     mWaitEventGroups[(*itEvents)].erase(itCurEvent);
     1103                    mWaitEventGroups[(*itEvents)].erase(itCurEvent++);
    10651104                    break;
    10661105                }
     
    12011240                                       const GuestWaitEventPayload *pPayload)
    12021241{
    1203     AssertReturn(!mfAborted, VERR_CANCELLED);
     1242    if (ASMAtomicReadBool(&mfAborted))
     1243        return VERR_CANCELLED;
    12041244
    12051245#ifdef VBOX_STRICT
     
    12821322    ASMAtomicWriteBool(&mfAborted, true);
    12831323
     1324#ifdef DEBUG_andy
     1325    LogFlowThisFunc(("Cancelling %p ...\n"));
     1326#endif
    12841327    return RTSemEventSignal(mEventSem);
    12851328}
  • trunk/src/VBox/Main/src-client/GuestFileImpl.cpp

    r49389 r49440  
    986986    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
    987987
     988    VBoxEventType_T evtType;
     989    ComPtr<IEvent> pIEvent;
    988990    int vrc = waitForEvent(pEvent, uTimeoutMS,
    989                            NULL /* Event type */, NULL /* IEvent */);
    990     if (RT_SUCCESS(vrc))
    991     {
    992         Assert(pEvent->Payload().Size() == sizeof(CALLBACKDATA_FILE_NOTIFY));
    993         const PCALLBACKDATA_FILE_NOTIFY pvCbData =
    994             (PCALLBACKDATA_FILE_NOTIFY)pEvent->Payload().Raw();
    995         Assert(pvCbData->uType == GUEST_FILE_NOTIFYTYPE_SEEK);
    996 
    997         if (puOffset)
    998             *puOffset = pvCbData->u.seek.uOffActual;
     991                           &evtType, pIEvent.asOutParam());
     992    if (RT_SUCCESS(vrc))
     993    {
     994        if (evtType == VBoxEventType_OnGuestFileOffsetChanged)
     995        {
     996            if (puOffset)
     997            {
     998                ComPtr<IGuestFileOffsetChangedEvent> pFileEvent = pIEvent;
     999                Assert(!pFileEvent.isNull());
     1000
     1001                HRESULT hr = pFileEvent->COMGETTER(Offset)((LONG64*)puOffset);
     1002                ComAssertComRC(hr);
     1003            }
     1004        }
     1005        else
     1006            vrc = VWRN_GSTCTL_OBJECTSTATE_CHANGED;
    9991007    }
    10001008
     
    10081016    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
    10091017
     1018    VBoxEventType_T evtType;
     1019    ComPtr<IEvent> pIEvent;
    10101020    int vrc = waitForEvent(pEvent, uTimeoutMS,
    1011                            NULL /* Event type */, NULL /* IEvent */);
    1012     if (RT_SUCCESS(vrc))
    1013     {
    1014         Assert(pEvent->Payload().Size() == sizeof(CALLBACKDATA_FILE_NOTIFY));
    1015         const PCALLBACKDATA_FILE_NOTIFY pvCbData =
    1016             (PCALLBACKDATA_FILE_NOTIFY)pEvent->Payload().Raw();
    1017         Assert(pvCbData->uType == GUEST_FILE_NOTIFYTYPE_READ);
    1018 
    1019         uint32_t cbRead = pvCbData->u.read.cbData;
    1020         if (   cbRead
    1021             && cbRead <= cbData)
    1022         {
    1023             memcpy(pvData,
    1024                    pvCbData->u.read.pvData, cbRead);
     1021                           &evtType, pIEvent.asOutParam());
     1022    if (RT_SUCCESS(vrc))
     1023    {
     1024        if (evtType == VBoxEventType_OnGuestFileRead)
     1025        {
     1026            ComPtr<IGuestFileReadEvent> pFileEvent = pIEvent;
     1027            Assert(!pFileEvent.isNull());
     1028
     1029            HRESULT hr;
     1030            if (pvData)
     1031            {
     1032                com::SafeArray <BYTE> data;
     1033                hr = pFileEvent->COMGETTER(Data)(ComSafeArrayAsOutParam(data));
     1034                ComAssertComRC(hr);
     1035                size_t cbRead = data.size();
     1036                if (   cbRead
     1037                    && cbRead <= cbData)
     1038                {
     1039                    memcpy(pvData, data.raw(), data.size());
     1040                }
     1041                else
     1042                    vrc = VERR_BUFFER_OVERFLOW;
     1043            }
     1044            if (pcbRead)
     1045            {
     1046                hr = pFileEvent->COMGETTER(Processed)((ULONG*)pcbRead);
     1047                ComAssertComRC(hr);
     1048            }
    10251049        }
    10261050        else
    1027             vrc = VERR_BUFFER_OVERFLOW;
    1028 
    1029         if (pcbRead)
    1030             *pcbRead = cbRead;
     1051            vrc = VWRN_GSTCTL_OBJECTSTATE_CHANGED;
    10311052    }
    10321053
     
    10381059{
    10391060    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
    1040 
     1061    /* pFileStatus is optional. */
     1062
     1063    VBoxEventType_T evtType;
     1064    ComPtr<IEvent> pIEvent;
    10411065    int vrc = waitForEvent(pEvent, uTimeoutMS,
    1042                            NULL /* Event type */, NULL /* IEvent */);
    1043     if (RT_SUCCESS(vrc))
    1044     {
    1045         Assert(pEvent->Payload().Size() == sizeof(CALLBACKDATA_FILE_NOTIFY));
    1046         const PCALLBACKDATA_FILE_NOTIFY pvCbData =
    1047             (PCALLBACKDATA_FILE_NOTIFY)pEvent->Payload().Raw();
    1048         /* Note: pvCbData->uType can be different types. */;
    1049 
    1050 
     1066                           &evtType, pIEvent.asOutParam());
     1067    if (RT_SUCCESS(vrc))
     1068    {
     1069        Assert(evtType == VBoxEventType_OnGuestFileStateChanged);
     1070        ComPtr<IGuestFileStateChangedEvent> pFileEvent = pIEvent;
     1071        Assert(!pFileEvent.isNull());
     1072
     1073        HRESULT hr;
     1074        if (pFileStatus)
     1075        {
     1076            hr = pFileEvent->COMGETTER(Status)(pFileStatus);
     1077            ComAssertComRC(hr);
     1078        }
     1079
     1080        ComPtr<IVirtualBoxErrorInfo> errorInfo;
     1081        hr = pFileEvent->COMGETTER(Error)(errorInfo.asOutParam());
     1082        ComAssertComRC(hr);
     1083
     1084        LONG lGuestRc;
     1085        hr = errorInfo->COMGETTER(ResultDetail)(&lGuestRc);
     1086        ComAssertComRC(hr);
     1087
     1088        LogFlowThisFunc(("resultDetail=%RI32 (%Rrc)\n",
     1089                         lGuestRc, lGuestRc));
     1090
     1091        if (RT_FAILURE((int)lGuestRc))
     1092            vrc = VERR_GSTCTL_GUEST_ERROR;
    10511093
    10521094        if (pGuestRc)
    1053             *pGuestRc = pvCbData->rc; /* int vs. uint32_t */
     1095            *pGuestRc = (int)lGuestRc;
    10541096    }
    10551097
     
    10621104    AssertPtrReturn(pEvent, VERR_INVALID_POINTER);
    10631105
     1106    VBoxEventType_T evtType;
     1107    ComPtr<IEvent> pIEvent;
    10641108    int vrc = waitForEvent(pEvent, uTimeoutMS,
    1065                            NULL /* Event type */, NULL /* IEvent */);
    1066     if (RT_SUCCESS(vrc))
    1067     {
    1068         Assert(pEvent->Payload().Size() == sizeof(CALLBACKDATA_FILE_NOTIFY));
    1069         const PCALLBACKDATA_FILE_NOTIFY pvCbData =
    1070             (PCALLBACKDATA_FILE_NOTIFY)pEvent->Payload().Raw();
    1071         Assert(pvCbData->uType == GUEST_FILE_NOTIFYTYPE_WRITE);
    1072 
    1073         if (pcbWritten)
    1074             *pcbWritten = pvCbData->u.write.cbWritten;
     1109                           &evtType, pIEvent.asOutParam());
     1110    if (RT_SUCCESS(vrc))
     1111    {
     1112        if (evtType == VBoxEventType_OnGuestFileWrite)
     1113        {
     1114            if (pcbWritten)
     1115            {
     1116                ComPtr<IGuestFileWriteEvent> pFileEvent = pIEvent;
     1117                Assert(!pFileEvent.isNull());
     1118
     1119                HRESULT hr = pFileEvent->COMGETTER(Processed)((ULONG*)pcbWritten);
     1120                ComAssertComRC(hr);
     1121            }
     1122        }
     1123        else
     1124            vrc = VWRN_GSTCTL_OBJECTSTATE_CHANGED;
    10751125    }
    10761126
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r49405 r49440  
    118118                int rc2 = mProcess->signalWaitEvent(aType, aEvent);
    119119#ifdef DEBUG
    120                 LogFlowThisFunc(("Signalling events of type=%ld, process=%p resulted in rc=%Rrc\n",
     120                LogFlowThisFunc(("Signalling events of type=%ld, pProcess=%p resulted in rc=%Rrc\n",
    121121                                 aType, &mProcess, rc2));
    122122#endif
     
    12381238    if (mData.mStatus != ProcessStatus_Started)
    12391239    {
    1240         LogFlowThisFunc(("Process not started (yet), nothing to terminate\n"));
     1240        LogFlowThisFunc(("Process not started state (state is %ld), skipping termination\n",
     1241                         mData.mStatus));
    12411242        return VINF_SUCCESS; /* Nothing to do (anymore). */
    12421243    }
     
    12981299        case ProcessStatus_TerminatedSignal:
    12991300        case ProcessStatus_TerminatedAbnormally:
     1301        case ProcessStatus_Down:
     1302            /* Nothing to wait for anymore. */
    13001303            waitResult = ProcessWaitResult_Terminate;
    13011304            break;
    1302         case ProcessStatus_Down:
    1303             waitResult = ProcessWaitResult_Terminate;
    1304             break;
    13051305
    13061306        case ProcessStatus_TimedOutKilled:
    1307             /* Fall through is intentional. */
    13081307        case ProcessStatus_TimedOutAbnormally:
     1308            /* Dito. */
    13091309            waitResult = ProcessWaitResult_Timeout;
    13101310            break;
    13111311
    1312         case ProcessStatus_Error:
    1313             waitResult = ProcessWaitResult_Error;
    1314             break;
    1315 
    13161312        case ProcessStatus_Started:
    1317         {
    13181313            switch (oldStatus)
    13191314            {
     1315                case ProcessStatus_Undefined:
    13201316                case ProcessStatus_Starting:
     1317                    /* Also wait for process start. */
    13211318                    if (fWaitFlags & ProcessWaitForFlag_Start)
    1322                     {
    13231319                        waitResult = ProcessWaitResult_Start;
    1324                     }
    13251320                    else
    13261321                    {
    13271322                        /*
    1328                          * If ProcessCreateFlag_WaitForProcessStartOnly was specified on process creation the
    1329                          * caller is not interested in getting further process statuses -- so just don't notify
    1330                          * anything here anymore and return.
    1331                          */
     1323                             * If ProcessCreateFlag_WaitForProcessStartOnly was specified on process creation the
     1324                             * caller is not interested in getting further process statuses -- so just don't notify
     1325                             * anything here anymore and return.
     1326                             */
    13321327                        if (uProcFlags & ProcessCreateFlag_WaitForProcessStartOnly)
    13331328                            waitResult = ProcessWaitResult_Start;
     
    13351330                    break;
    13361331
     1332                case ProcessStatus_Started:
     1333                    /* Only wait for process start. */
     1334                    if (fWaitFlags == ProcessWaitForFlag_Start)
     1335                        waitResult = ProcessWaitResult_Start;
     1336                    break;
     1337
    13371338                default:
    1338                     /* No result available (yet). */
     1339                    AssertMsgFailed(("Unhandled old status %ld before new status 'started'\n",
     1340                                     oldStatus));
     1341                    waitResult = ProcessWaitResult_Start;
    13391342                    break;
    13401343            }
    13411344            break;
    1342         }
     1345
     1346        case ProcessStatus_Error:
     1347            /* Nothing to wait for anymore. */
     1348            waitResult = ProcessWaitResult_Error;
     1349            break;
    13431350
    13441351        case ProcessStatus_Undefined:
    13451352        case ProcessStatus_Starting:
    1346             /* No result available yet. */
    1347             break;
    1348 
    1349         default:
    1350             AssertMsgFailed(("Unhandled process status %ld\n", newStatus));
     1353            /* No result available yet, leave wait
     1354             * flags untouched. */
    13511355            break;
    13521356    }
     
    14091413        if (pGuestRc)
    14101414            *pGuestRc = mData.mLastError; /* Return last set error. */
     1415        LogFlowThisFunc(("Process is in error state (guestRc=%Rrc)\n", mData.mLastError));
    14111416        return VERR_GSTCTL_GUEST_ERROR;
    14121417    }
     
    14191424        if (pGuestRc)
    14201425            *pGuestRc = mData.mLastError; /* Return last set error (if any). */
     1426        LogFlowThisFunc(("Nothing to wait for (guestRc=%Rrc)\n", mData.mLastError));
    14211427        return RT_SUCCESS(mData.mLastError) ? VINF_SUCCESS : VERR_GSTCTL_GUEST_ERROR;
    14221428    }
    1423 
    1424     alock.release(); /* Release lock before waiting. */
    14251429
    14261430    /* Adjust timeout. Passing 0 means RT_INDEFINITE_WAIT. */
     
    14451449    if (RT_FAILURE(vrc))
    14461450        return vrc;
     1451
     1452    alock.release(); /* Release lock before waiting. */
    14471453
    14481454    /*
     
    14991505    ComPtr<IEvent> pIEvent;
    15001506    int vrc = waitForEvent(pEvent, uTimeoutMS,
    1501                                  &evtType, pIEvent.asOutParam());
     1507                           &evtType, pIEvent.asOutParam());
    15021508    if (RT_SUCCESS(vrc))
    15031509    {
     
    15451551    {
    15461552        vrc = waitForEvent(pEvent, uTimeoutMS,
    1547                                  &evtType, pIEvent.asOutParam());
     1553                           &evtType, pIEvent.asOutParam());
    15481554        if (RT_SUCCESS(vrc))
    15491555        {
     
    16401646        ComAssertComRC(hr);
    16411647
    1642         LogFlowThisFunc(("procStatus=%RU32, resultDetail=%RI32 (rc=%Rrc)\n",
     1648        LogFlowThisFunc(("Got procStatus=%RU32, guestRc=%RI32 (%Rrc)\n",
    16431649                         procStatus, lGuestRc, lGuestRc));
    16441650
     
    17721778    ReturnComNotImplemented();
    17731779#else
     1780    LogFlowThisFuncEnter();
     1781
    17741782    if (aToRead == 0)
    17751783        return setError(E_INVALIDARG, tr("The size to read is zero"));
  • trunk/src/VBox/Main/src-client/GuestSessionImplTasks.cpp

    r49349 r49440  
    317317    /* Startup process. */
    318318    ComObjPtr<GuestProcess> pProcess; int guestRc;
    319     rc = pSession->processCreateExInteral(procInfo, pProcess);
    320319    if (RT_SUCCESS(rc))
     320        rc = pSession->processCreateExInteral(procInfo, pProcess);
     321    if (RT_SUCCESS(rc))
     322    {
     323        Assert(!pProcess.isNull());
    321324        rc = pProcess->startProcess(30 * 1000 /* 30s timeout */,
    322325                                    &guestRc);
     326    }
     327
    323328    if (RT_FAILURE(rc))
    324329    {
     
    772777                         * to the destination -> access denied. */
    773778                        setProgressErrorMsg(VBOX_E_IPRT_ERROR,
    774                                             Utf8StrFmt(GuestSession::tr("Access denied when copying file \"%s\" to \"%s\""),
     779                                            Utf8StrFmt(GuestSession::tr("Unable to write \"%s\" to \"%s\": Access denied"),
    775780                                            mSource.c_str(), mDest.c_str()));
    776781                        rc = VERR_GENERAL_FAILURE; /* Fudge. */
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