VirtualBox

Changeset 45697 in vbox


Ignore:
Timestamp:
Apr 24, 2013 1:30:50 PM (12 years ago)
Author:
vboxsync
Message:

GuestCtrl: Various bugfixes required for test driver to pass.

Location:
trunk/src/VBox
Files:
6 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControl.h

    r45604 r45697  
    9797    /** Event semaphore to serialize access. */
    9898    RTSEMEVENTMULTI            Event;
    99     /** Flag indicating if this request is asynchronous or not. */
     99    /** Flag indicating if this request is asynchronous or not.
     100     *  If asynchronous, this request will be deleted automatically
     101     *  on completion. Otherwise the caller has to delete the
     102     *  request again. */
    100103    bool                       fAsync;
    101104    /** The request type to handle. */
     
    313316    /** Node. */
    314317    RTLISTNODE                      Node;
     318    /** Number of references using this struct. */
     319    uint32_t                        cRefs;
    315320    /** The worker thread. */
    316321    RTTHREAD                        Thread;
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlProcess.cpp

    r45610 r45697  
    4747*******************************************************************************/
    4848static int                  gstcntlProcessAssignPID(PVBOXSERVICECTRLPROCESS pThread, uint32_t uPID);
     49static int                  gstcntlProcessLock(PVBOXSERVICECTRLPROCESS pProcess);
    4950static int                  gstcntlProcessRequestCancel(PVBOXSERVICECTRLREQUEST pThread);
    5051static int                  gstcntlProcessSetupPipe(const char *pszHowTo, int fd, PRTHANDLE ph, PRTHANDLE *pph, PRTPIPE phPipe);
     52static int                  gstcntlProcessUnlock(PVBOXSERVICECTRLPROCESS pProcess);
    5153
    5254/**
     
    148150                       pProcess->uPID);
    149151
     152    /* Do *not* set pThread->fShutdown or other stuff here!
     153     * The guest thread loop will do that as soon as it processes the quit message. */
     154
     155    PVBOXSERVICECTRLREQUEST pRequest;
     156    int rc = GstCntlProcessRequestAlloc(&pRequest, VBOXSERVICECTRLREQUEST_PROC_TERM);
     157    if (RT_SUCCESS(rc))
     158    {
     159        rc = GstCntlProcessPerform(pProcess, pRequest,
     160                                   true /* Async */);
     161        if (RT_FAILURE(rc))
     162            VBoxServiceVerbose(3, "[PID %RU32]: Sending termination request failed with rc=%Rrc\n",
     163                               pProcess->uPID, rc);
     164        /* Deletion of pRequest will be done on request completion (asynchronous). */
     165    }
     166
     167    return rc;
     168}
     169
     170
     171/**
     172 * Releases a previously acquired guest process (decreses the refcount).
     173 *
     174 * @param   pProcess            Process to unlock.
     175 */
     176void GstCntlProcessRelease(const PVBOXSERVICECTRLPROCESS pProcess)
     177{
     178    AssertPtrReturnVoid(pProcess);
     179
    150180    int rc = RTCritSectEnter(&pProcess->CritSect);
    151181    if (RT_SUCCESS(rc))
    152182    {
    153         if (pProcess->pRequest)
    154         {
    155             rc = gstcntlProcessRequestCancel(pProcess->pRequest);
    156             if (RT_FAILURE(rc))
    157                 VBoxServiceError("[PID %RU32]: Cancelling current request failed, rc=%Rrc\n",
    158                                  pProcess->uPID, rc);
    159         }
    160 
    161         /* Do *not* set pThread->fShutdown or other stuff here!
    162          * The guest thread loop will do that as soon as it processes the quit message. */
    163 
    164         PVBOXSERVICECTRLREQUEST pRequest;
    165         rc = GstCntlProcessRequestAlloc(&pRequest, VBOXSERVICECTRLREQUEST_PROC_TERM);
    166         if (RT_SUCCESS(rc))
    167         {
    168             rc = GstCntlProcessPerform(pProcess, pRequest,
    169                                        true /* Async */);
    170             if (RT_FAILURE(rc))
    171                 VBoxServiceVerbose(3, "[PID %RU32]: Sending termination request failed with rc=%Rrc\n",
    172                                    pProcess->uPID, rc);
    173             /* Deletion of pRequest will be done on request completion. */
    174         }
    175 
    176         int rc2 = RTCritSectLeave(&pProcess->CritSect);
    177         AssertRC(rc2);
    178     }
    179 
    180     return rc;
    181 }
    182 
    183 
    184 /**
    185  * Releases (unlocks) a previously locked guest process.
    186  *
    187  * @param   pProcess            Process to unlock.
    188  */
    189 void GstCntlProcessRelease(const PVBOXSERVICECTRLPROCESS pProcess)
    190 {
    191     AssertPtrReturnVoid(pProcess);
    192 
    193     int rc = RTCritSectLeave(&pProcess->CritSect);
    194     AssertRC(rc);
     183        Assert(pProcess->cRefs);
     184        pProcess->cRefs--;
     185        rc = RTCritSectLeave(&pProcess->CritSect);
     186        AssertRC(rc);
     187    }
    195188}
    196189
     
    269262
    270263
     264static const char* gstcntlProcessPollHandleToString(uint32_t idPollHnd)
     265{
     266    switch (idPollHnd)
     267    {
     268        case VBOXSERVICECTRLPIPEID_UNKNOWN:
     269            return "unknown";
     270        case VBOXSERVICECTRLPIPEID_STDIN:
     271            return "stdin";
     272        case VBOXSERVICECTRLPIPEID_STDIN_WRITABLE:
     273            return "stdin_writable";
     274        case VBOXSERVICECTRLPIPEID_STDOUT:
     275            return "stdout";
     276        case VBOXSERVICECTRLPIPEID_STDERR:
     277            return "stderr";
     278        case VBOXSERVICECTRLPIPEID_IPC_NOTIFY:
     279            return "ipc_notify";
     280        default:
     281            break;
     282    }
     283
     284    return "unknown";
     285}
     286
     287
    271288/**
    272289 * Handle an error event on standard input.
     
    301318
    302319#ifdef DEBUG
    303     VBoxServiceVerbose(4, "gstcntlProcessHandleOutputError: fPollEvt=0x%x, idPollHnd=%u\n",
    304                        fPollEvt, idPollHnd);
     320    VBoxServiceVerbose(4, "gstcntlProcessHandleOutputError: fPollEvt=0x%x, idPollHnd=%s\n",
     321                       fPollEvt, gstcntlProcessPollHandleToString(idPollHnd));
    305322#endif
    306323
     
    317334        && cbReadable)
    318335    {
    319         VBoxServiceVerbose(3, "gstcntlProcessHandleOutputError: idPollHnd=%RU32 has %zu bytes left, vetoing close\n",
    320                            idPollHnd, cbReadable);
     336        VBoxServiceVerbose(3, "gstcntlProcessHandleOutputError: idPollHnd=%s has %zu bytes left, vetoing close\n",
     337                           gstcntlProcessPollHandleToString(idPollHnd), cbReadable);
    321338
    322339        /* Veto closing the pipe yet because there's still stuff to read
     
    326343    }
    327344    else
    328         VBoxServiceVerbose(3, "gstcntlProcessHandleOutputError: idPollHnd=%RU32 will be closed\n",
    329                            idPollHnd);
     345        VBoxServiceVerbose(3, "gstcntlProcessHandleOutputError: idPollHnd=%s will be closed\n",
     346                           gstcntlProcessPollHandleToString(idPollHnd));
    330347
    331348    if (   *phPipeR != NIL_RTPIPE
     
    354371                                           PRTPIPE phPipeR, uint32_t idPollHnd)
    355372{
    356 #if 0
    357     VBoxServiceVerbose(4, "GstCntlProcessHandleOutputEvent: fPollEvt=0x%x, idPollHnd=%u\n",
    358                        fPollEvt, idPollHnd);
     373#ifdef DEBUG_andy
     374    VBoxServiceVerbose(4, "GstCntlProcessHandleOutputEvent: fPollEvt=0x%x, idPollHnd=%s\n",
     375                       fPollEvt, gstcntlProcessPollHandleToString(idPollHnd));
    359376#endif
    360377
     
    439456
    440457
    441 static int gstcntlProcessRequestHandle(RTPOLLSET hPollSet, uint32_t fPollEvt,
    442                                        PRTPIPE phStdInW, PRTPIPE phStdOutR, PRTPIPE phStdErrR,
    443                                        PVBOXSERVICECTRLPROCESS pProcess, PVBOXSERVICECTRLREQUEST pRequest)
     458static int gstcntlProcessRequestHandle(PVBOXSERVICECTRLPROCESS pProcess, PVBOXSERVICECTRLREQUEST pRequest,
     459                                       RTPOLLSET hPollSet, uint32_t fPollEvt,
     460                                       PRTPIPE phStdInW, PRTPIPE phStdOutR, PRTPIPE phStdErrR)
    444461{
    445462    AssertPtrReturn(phStdInW, VERR_INVALID_POINTER);
     
    530547
    531548        case VBOXSERVICECTRLREQUEST_PROC_TERM:
    532             ASMAtomicXchgBool(&pProcess->fShutdown, true);
     549            pProcess->fShutdown = true;
    533550            fDefer = true;
    534551            break;
     
    605622                       pProcess->uPID, pProcess->StartupInfo.szCmd, pProcess->uContextID,
    606623                       pProcess->StartupInfo.szUser, pProcess->StartupInfo.uTimeLimitMS);
    607     VBGLR3GUESTCTRLCMDCTX ctx = { pProcess->uClientID, pProcess->uContextID };
    608     rc = VbglR3GuestCtrlProcCbStatus(&ctx,
     624    VBGLR3GUESTCTRLCMDCTX ctxStart = { pProcess->uClientID, pProcess->uContextID };
     625    rc = VbglR3GuestCtrlProcCbStatus(&ctxStart,
    609626                                     pProcess->uPID, PROC_STS_STARTED, 0 /* u32Flags */,
    610627                                     NULL /* pvData */, 0 /* cbData */);
     
    613630     * Process input, output, the test pipe and client requests.
    614631     */
    615     PVBOXSERVICECTRLREQUEST pReq = NULL;
    616632    while (   RT_SUCCESS(rc)
    617633           && RT_UNLIKELY(!pProcess->fShutdown))
     
    640656                                                         phStdOutR, idPollHnd);
    641657                    break;
     658
    642659                case VBOXSERVICECTRLPIPEID_STDERR:
    643660                    rc = gstcntlProcessHandleOutputEvent(hPollSet, fPollEvt,
     
    646663
    647664                case VBOXSERVICECTRLPIPEID_IPC_NOTIFY:
    648                     pReq = pProcess->pRequest; /** @todo Implement request queue. */
    649                     rc = gstcntlProcessRequestHandle(hPollSet, fPollEvt,
    650                                                      phStdInW, phStdOutR, phStdErrR,
    651                                                      pProcess, pReq);
    652                     if (rc == VINF_AIO_TASK_PENDING)
    653                         VBoxServiceVerbose(4, "[PID %RU32]: pRequest=%p will be handled deferred\n",
    654                                            pProcess->uPID, pReq);
     665#ifdef DEBUG_andy
     666                    VBoxServiceVerbose(4, "[PID %RU32]: IPC notify\n", pProcess->uPID);
     667#endif
     668                    rc = gstcntlProcessLock(pProcess);
     669                    if (RT_SUCCESS(rc))
     670                    {
     671                        /** @todo Implement request queue. */
     672                        rc = gstcntlProcessRequestHandle(pProcess, pProcess->pRequest,
     673                                                         hPollSet, fPollEvt,
     674                                                         phStdInW, phStdOutR, phStdErrR);
     675                        if (rc != VINF_AIO_TASK_PENDING)
     676                        {
     677                            pProcess->pRequest = NULL;
     678                        }
     679                        else
     680                            VBoxServiceVerbose(4, "[PID %RU32]: pRequest=%p will be handled deferred\n",
     681                                               pProcess->uPID, pProcess->pRequest);
     682
     683                        rc2 = gstcntlProcessUnlock(pProcess);
     684                        AssertRC(rc2);
     685                    }
    655686                    break;
    656687
     
    664695        }
    665696#ifdef DEBUG_andy
    666         VBoxServiceVerbose(4, "[PID %RU32]: Polling done, pollRc=%Rrc, pollCnt=%u, idPollHnd=%RU32, rc=%Rrc, fProcessAlive=%RTbool, fShutdown=%RTbool\n",
    667                            pProcess->uPID, rc2, RTPollSetGetCount(hPollSet), idPollHnd, rc, fProcessAlive, pProcess->fShutdown);
     697        VBoxServiceVerbose(4, "[PID %RU32]: Polling done, pollRc=%Rrc, pollCnt=%RU32, idPollHnd=%s, rc=%Rrc, fProcessAlive=%RTbool, fShutdown=%RTbool\n",
     698                           pProcess->uPID, rc2, RTPollSetGetCount(hPollSet), gstcntlProcessPollHandleToString(idPollHnd), rc, fProcessAlive, pProcess->fShutdown);
     699        VBoxServiceVerbose(4, "[PID %RU32]: stdOut=%s, stdErrR=%s\n",
     700                           pProcess->uPID,
     701                           *phStdOutR == NIL_RTPIPE ? "closed" : "open",
     702                           *phStdErrR == NIL_RTPIPE ? "closed" : "open");
    668703#endif
    669704        if (RT_UNLIKELY(pProcess->fShutdown))
     
    677712            rc2 = RTProcWaitNoResume(hProcess, RTPROCWAIT_FLAGS_NOBLOCK, &ProcessStatus);
    678713#ifdef DEBUG_andy
    679             VBoxServiceVerbose(4, "[PID %RU32]: RTProcWaitNoResume=%Rrc, stdOut=%s, stdErrR=%s\n",
    680                                pProcess->uPID, rc2,
    681                                *phStdOutR == NIL_RTPIPE ? "closed" : "open",
    682                                *phStdErrR == NIL_RTPIPE ? "closed" : "open");
     714            VBoxServiceVerbose(4, "[PID %RU32]: RTProcWaitNoResume=%Rrc\n",
     715                               pProcess->uPID, rc2);
    683716#endif
    684717            if (RT_SUCCESS_NP(rc2))
     
    707740            && *phStdOutR == NIL_RTPIPE
    708741            && *phStdErrR == NIL_RTPIPE)
     742        {
     743            VBoxServiceVerbose(3, "[PID %RU32]: All pipes closed, process not alive anymore, bailing out ...\n",
     744                                   pProcess->uPID);
    709745            break;
     746        }
    710747
    711748        /*
     
    713750         */
    714751        uint32_t cMilliesLeft = RT_INDEFINITE_WAIT;
    715         if (pProcess->StartupInfo.uTimeLimitMS != RT_INDEFINITE_WAIT)
     752        if (   pProcess->StartupInfo.uTimeLimitMS != RT_INDEFINITE_WAIT
     753            && pProcess->StartupInfo.uTimeLimitMS != 0)
    716754        {
    717755            uint64_t u64Now = RTTimeMilliTS();
     
    746784    }
    747785
    748     rc2 = RTCritSectEnter(&pProcess->CritSect);
    749     if (RT_SUCCESS(rc2))
    750     {
    751         ASMAtomicXchgBool(&pProcess->fShutdown, true);
    752 
    753         rc2 = RTCritSectLeave(&pProcess->CritSect);
    754         AssertRC(rc2);
    755     }
     786    VBoxServiceVerbose(2, "[PID %RU32]: Process loop ended with rc=%Rrc\n",
     787                       pProcess->uPID, rc);
     788
     789    /* Signal that this thread is in progress of shutting down. */
     790    ASMAtomicXchgBool(&pProcess->fShutdown, true);
    756791
    757792    /*
     
    762797        if (MsProcessKilled == UINT64_MAX)
    763798        {
    764             VBoxServiceVerbose(3, "[PID %RU32]: Is still alive and not killed yet\n",
     799            VBoxServiceVerbose(2, "[PID %RU32]: Is still alive and not killed yet\n",
    765800                               pProcess->uPID);
    766801
    767802            MsProcessKilled = RTTimeMilliTS();
    768             RTProcTerminate(hProcess);
     803            rc2 = RTProcTerminate(hProcess);
     804            if (RT_FAILURE(rc))
     805                VBoxServiceError("PID %RU32]: Killing process failed with rc=%Rrc\n",
     806                                 pProcess->uPID, rc);
    769807            RTThreadSleep(500);
    770808        }
     
    786824                VBoxServiceVerbose(4, "[PID %RU32]: Kill attempt %d/10: Trying to terminate ...\n",
    787825                                   pProcess->uPID, i + 1);
    788                 RTProcTerminate(hProcess);
     826                rc2 = RTProcTerminate(hProcess);
     827                if (RT_FAILURE(rc))
     828                    VBoxServiceError("PID %RU32]: Killing process failed with rc=%Rrc\n",
     829                                     pProcess->uPID, rc);
    789830            }
    790831            RTThreadSleep(i >= 5 ? 2000 : 500);
     
    792833
    793834        if (fProcessAlive)
    794             VBoxServiceVerbose(3, "[PID %RU32]: Could not be killed\n", pProcess->uPID);
    795 
    796         if (   pReq /* Handle deferred termination request. */
    797             && pReq->enmType == VBOXSERVICECTRLREQUEST_PROC_TERM)
    798         {
    799             rc2 = gstcntlProcessRequestComplete(pReq,
    800                                                 fProcessAlive ? VINF_SUCCESS : VERR_PROCESS_RUNNING);
    801             AssertRC(rc2);
    802         }
    803         else if (pReq)
    804             AssertMsgFailed(("Unable to handle unknown deferred request (type: %RU32)\n", pReq->enmType));
     835            VBoxServiceError("[PID %RU32]: Could not be killed\n", pProcess->uPID);
     836    }
     837
     838    rc2 = gstcntlProcessLock(pProcess);
     839    if (RT_SUCCESS(rc2))
     840    {
     841        if (pProcess->pRequest)
     842        {
     843            switch (pProcess->pRequest->enmType)
     844            {
     845                /* Handle deferred termination request. */
     846                case VBOXSERVICECTRLREQUEST_PROC_TERM:
     847                    rc2 = gstcntlProcessRequestComplete(pProcess->pRequest,
     848                                                        fProcessAlive ? VINF_SUCCESS : VERR_PROCESS_RUNNING);
     849                    AssertRC(rc2);
     850                    break;
     851
     852                /* Cancel all others.
     853                 ** @todo Clear request queue as soon as it's implemented. */
     854                default:
     855                    rc2 = gstcntlProcessRequestCancel(pProcess->pRequest);
     856                    AssertRC(rc2);
     857                    break;
     858            }
     859
     860            pProcess->pRequest = NULL;
     861        }
     862#ifdef DEBUG
     863        else
     864            VBoxServiceVerbose(3, "[PID %RU32]: No pending request found\n", pProcess->uPID);
     865#endif
     866        rc2 = gstcntlProcessUnlock(pProcess);
     867        AssertRC(rc2);
    805868    }
    806869
     
    877940        if (!(pProcess->StartupInfo.uFlags & EXECUTEPROCESSFLAG_WAIT_START))
    878941        {
    879             VBGLR3GUESTCTRLCMDCTX ctx = { pProcess->uClientID, pProcess->uContextID };
    880             rc2 = VbglR3GuestCtrlProcCbStatus(&ctx,
     942            VBGLR3GUESTCTRLCMDCTX ctxEnd = { pProcess->uClientID, pProcess->uContextID };
     943            rc2 = VbglR3GuestCtrlProcCbStatus(&ctxEnd,
    881944                                              pProcess->uPID, uStatus, uFlags,
    882945                                              NULL /* pvData */, 0 /* cbData */);
     
    890953    }
    891954
    892     VBoxServiceVerbose(3, "[PID %RU32]: Process loop ended with rc=%Rrc\n",
     955    VBoxServiceVerbose(3, "[PID %RU32]: Process loop returned with rc=%Rrc\n",
    893956                       pProcess->uPID, rc);
    894957    return rc;
     
    9931056        return VINF_SUCCESS;
    9941057
    995     VBoxServiceVerbose(4, "Cancelling request=0x%p\n", pReq);
     1058    VBoxServiceVerbose(4, "Cancelling outstanding request=0x%p\n", pReq);
    9961059
    9971060    return RTSemEventMultiSignal(pReq->Event);
     
    10341097    if (RT_SUCCESS(rc))
    10351098    {
    1036         VBoxServiceVerbose(4, "Performed request with rc=%Rrc, cbData=%u\n",
     1099        VBoxServiceVerbose(4, "Performed request with rc=%Rrc, cbData=%RU32\n",
    10371100                           pReq->rc, pReq->cbData);
    10381101
     
    17831846
    17841847
     1848static int gstcntlProcessLock(PVBOXSERVICECTRLPROCESS pProcess)
     1849{
     1850    AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
     1851    int rc = RTCritSectEnter(&pProcess->CritSect);
     1852    AssertRC(rc);
     1853    return rc;
     1854}
     1855
     1856
    17851857/**
    17861858 * Thread main routine for a started process.
     
    17961868    AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
    17971869    return gstcntlProcessProcessWorker(pProcess);
     1870}
     1871
     1872
     1873static int gstcntlProcessUnlock(PVBOXSERVICECTRLPROCESS pProcess)
     1874{
     1875    AssertPtrReturn(pProcess, VERR_INVALID_POINTER);
     1876    int rc = RTCritSectLeave(&pProcess->CritSect);
     1877    AssertRC(rc);
     1878    return rc;
    17981879}
    17991880
     
    18841965    int rc = VINF_SUCCESS;
    18851966
    1886     AssertMsgReturn(pProcess->pRequest == NULL,
    1887                     ("Another request still is in progress (%p)\n", pProcess->pRequest),
    1888                     VERR_ACCESS_DENIED);
    1889 
    18901967    if (   ASMAtomicReadBool(&pProcess->fShutdown)
    18911968        || ASMAtomicReadBool(&pProcess->fStopped))
     
    18951972    else
    18961973    {
    1897         VBoxServiceVerbose(3, "[PID %RU32]: Sending pRequest=%p\n",
    1898                            pProcess->uPID, pRequest);
    1899 
    1900         /* Set request structure pointer. */
    1901         pProcess->pRequest = pRequest;
    1902 
    1903         /** @todo To speed up simultaneous guest process handling we could add a worker threads
    1904          *        or queue in order to wait for the request to happen. Later. */
    1905         /* Wake up guest thread by sending a wakeup byte to the notification pipe so
    1906          * that RTPoll unblocks (returns) and we then can do our requested operation. */
    1907         Assert(pProcess->hNotificationPipeW != NIL_RTPIPE);
    1908         size_t cbWritten = 0;
     1974        rc = gstcntlProcessLock(pProcess);
    19091975        if (RT_SUCCESS(rc))
    1910             rc = RTPipeWrite(pProcess->hNotificationPipeW, "i", 1, &cbWritten);
    1911 
    1912         if (RT_SUCCESS(rc))
    1913         {
    1914             Assert(cbWritten);
    1915             if (!fAsync)
     1976        {
     1977            AssertMsgReturn(pProcess->pRequest == NULL,
     1978                            ("Another request still is in progress (%p)\n", pProcess->pRequest),
     1979                            VERR_ALREADY_EXISTS);
     1980
     1981            VBoxServiceVerbose(3, "[PID %RU32]: Sending pRequest=%p\n",
     1982                               pProcess->uPID, pRequest);
     1983
     1984            /* Set request structure pointer. */
     1985            pProcess->pRequest = pRequest;
     1986
     1987            /** @todo To speed up simultaneous guest process handling we could add a worker threads
     1988             *        or queue in order to wait for the request to happen. Later. */
     1989            /* Wake up guest thread by sending a wakeup byte to the notification pipe so
     1990             * that RTPoll unblocks (returns) and we then can do our requested operation. */
     1991            Assert(pProcess->hNotificationPipeW != NIL_RTPIPE);
     1992            size_t cbWritten = 0;
     1993            if (RT_SUCCESS(rc))
     1994                rc = RTPipeWrite(pProcess->hNotificationPipeW, "i", 1, &cbWritten);
     1995
     1996            int rcWait = VINF_SUCCESS;
     1997            if (RT_SUCCESS(rc))
    19161998            {
    1917                 VBoxServiceVerbose(3, "[PID %RU32]: Waiting for response on pRequest=%p, enmType=%u, pvData=0x%p, cbData=%u\n",
    1918                                    pProcess->uPID, pRequest, pRequest->enmType, pRequest->pvData, pRequest->cbData);
    1919 
    1920                 rc = GstCntlProcessRequestWait(pRequest);
    1921                 if (RT_SUCCESS(rc))
     1999                Assert(cbWritten);
     2000                if (!fAsync)
     2001                {
     2002                    VBoxServiceVerbose(3, "[PID %RU32]: Waiting for response on pRequest=%p, enmType=%u, pvData=0x%p, cbData=%u\n",
     2003                                       pProcess->uPID, pRequest, pRequest->enmType, pRequest->pvData, pRequest->cbData);
     2004
     2005                    rc = gstcntlProcessUnlock(pProcess);
     2006                    if (RT_SUCCESS(rc))
     2007                        rcWait = GstCntlProcessRequestWait(pRequest);
     2008
     2009                    /* NULL current request in any case. */
    19222010                    pProcess->pRequest = NULL;
     2011                }
    19232012            }
     2013
     2014            if (   RT_FAILURE(rc)
     2015                || fAsync)
     2016            {
     2017                int rc2 = gstcntlProcessUnlock(pProcess);
     2018                AssertRC(rc2);
     2019            }
     2020
     2021            if (RT_SUCCESS(rc))
     2022                rc = rcWait;
    19242023        }
    19252024    }
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlSession.cpp

    r45604 r45697  
    553553                                         &startupInfo.uFlags,
    554554                                         /* Arguments */
    555                                          startupInfo.szArgs,     sizeof(startupInfo.szArgs), &startupInfo.uNumArgs,
     555                                         startupInfo.szArgs,     sizeof(startupInfo.szArgs),    &startupInfo.uNumArgs,
    556556                                         /* Environment */
    557                                          startupInfo.szEnv, &startupInfo.cbEnv, &startupInfo.uNumEnvVars,
     557                                         startupInfo.szEnv,      &startupInfo.cbEnv,            &startupInfo.uNumEnvVars,
    558558                                         /* Credentials; for hosts with VBox < 4.3 (protocol version 1).
    559559                                          * For protocl v2 and up the credentials are part of the session
     
    601601                         rc, pHostCtx->uProtocol, pHostCtx->uNumParms);
    602602
    603         /*
    604          * Note: The context ID can be 0 because we mabye weren't able to fetch the command
    605          *       from the host. The host in case has to deal with that!
    606          */
    607         int rc2 = VbglR3GuestCtrlProcCbStatus(pHostCtx, 0 /* PID, invalid */,
    608                                               PROC_STS_ERROR, rc,
    609                                               NULL /* pvData */, 0 /* cbData */);
    610         if (RT_FAILURE(rc2))
    611         {
    612             VBoxServiceError("Error sending start process status to host, rc=%Rrc\n", rc2);
    613             if (RT_SUCCESS(rc))
    614                 rc = rc2;
     603        /* Don't report back if we didn't supply sufficient buffer for getting
     604         * the actual command -- we don't have the matching context ID. */
     605        if (rc != VERR_TOO_MUCH_DATA)
     606        {
     607            /*
     608             * Note: The context ID can be 0 because we mabye weren't able to fetch the command
     609             *       from the host. The host in case has to deal with that!
     610             */
     611            int rc2 = VbglR3GuestCtrlProcCbStatus(pHostCtx, 0 /* PID, invalid */,
     612                                                  PROC_STS_ERROR, rc,
     613                                                  NULL /* pvData */, 0 /* cbData */);
     614            if (RT_FAILURE(rc2))
     615                VBoxServiceError("Error sending start process status to host, rc=%Rrc\n", rc2);
    615616        }
    616617    }
     
    881882    int rc = VINF_SUCCESS;
    882883
    883     /* Only anonymous sessions (that is, sessions which run with local
     884    /** @todo Implement asynchronous handling of all commands to speed up overall
     885     *        performance for handling multiple guest processes at once. At the moment
     886     *        only one guest process at a time can and will be served. */
     887
     888    /**
     889     * Only anonymous sessions (that is, sessions which run with local
    884890     * service privileges) or forked session processes can do certain
    885      * operations. */
     891     * operations.
     892     */
    886893    bool fImpersonated = (   pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_FORK
    887894                          || pSession->uFlags & VBOXSERVICECTRLSESSION_FLAG_ANONYMOUS);
     
    12551262
    12561263/**
    1257  * Finds a (formerly) started guest process given by its PID and locks it.
    1258  * Must be unlocked by the caller with GstCntlProcessRelease().
     1264 * Finds a (formerly) started guest process given by its PID and increses
     1265 * its reference count. Must be decreased by the caller with GstCntlProcessRelease().
    12591266 *
    12601267 * @return  PVBOXSERVICECTRLTHREAD      Locked guest process if found, otherwise NULL.
     
    12771284                rc = RTCritSectEnter(&pCurProcess->CritSect);
    12781285                if (RT_SUCCESS(rc))
     1286                {
     1287                    pCurProcess->cRefs++;
     1288                    rc = RTCritSectLeave(&pCurProcess->CritSect);
     1289                    AssertRC(rc);
     1290                }
     1291
     1292                if (RT_SUCCESS(rc))
    12791293                    pProcess = pCurProcess;
    12801294                break;
     
    12821296        }
    12831297
    1284         int rc2 = RTCritSectLeave(&pSession->CritSect);
    1285         if (RT_SUCCESS(rc))
    1286             rc = rc2;
     1298        rc = RTCritSectLeave(&pSession->CritSect);
     1299        AssertRC(rc);
    12871300    }
    12881301
  • trunk/src/VBox/HostServices/GuestControl/service.cpp

    r45482 r45697  
    332332                                rc = VERR_INVALID_PARAMETER;
    333333
    334                             if (paDstParms[i].u.pointer.size < mpParms[i].u.pointer.size)
     334                            if (   RT_SUCCESS(rc)
     335                                && paDstParms[i].u.pointer.size < mpParms[i].u.pointer.size)
    335336                                rc = VERR_BUFFER_OVERFLOW;
    336337
     
    525526        mHostCmdRc    = VINF_SUCCESS;
    526527        mHostCmdTries = 0;
     528        mPeekCount    = 0;
    527529
    528530        return nextItem;
     
    630632        int rc = VINF_SUCCESS;
    631633
    632         LogFlowFunc(("[Client %RU32] pConnection=%p, mHostCmdRc=%Rrc, mHostCmdTries=%RU32\n",
    633                       mID, pConnection, mHostCmdRc, mHostCmdTries));
     634        LogFlowFunc(("[Client %RU32] pConnection=%p, mHostCmdRc=%Rrc, mHostCmdTries=%RU32, mPeekCount=%RU32\n",
     635                      mID, pConnection, mHostCmdRc, mHostCmdTries, mPeekCount));
    634636
    635637        mHostCmdRc = SendReply(pConnection, pHostCmd);
     
    644646            /*
    645647             * If the client understood the message but supplied too little buffer space
    646              * don't send this message again and drop it after 3 unsuccessful attempts.
    647              * The host then should take care of next actions (maybe retry it with a smaller buffer).
     648             * don't send this message again and drop it after 6 unsuccessful attempts.
     649             *
     650             * Note: Due to legacy reasons this the retry counter has to be even because on
     651             *       every peek there will be the actual command retrieval from the client side.
     652             *       To not get the actual command if the client actually only wants to peek for
     653             *       the next command, there needs to be two rounds per try, e.g. 3 rounds = 6 tries.
     654             *
     655             ** @todo Fix the mess stated above. GUEST_MSG_WAIT should be become GUEST_MSG_PEEK, *only*
     656             *        (and every time) returning the next upcoming host command (if any, blocking). Then
     657             *        it's up to the client what to do next, either peeking again or getting the actual
     658             *        host command via an own GUEST_ type message.
    648659             */
    649660            if (mHostCmdRc == VERR_TOO_MUCH_DATA)
    650661            {
    651                 if (mHostCmdTries >= 3)
     662                if (mHostCmdTries == 6)
    652663                    fRemove = true;
    653664            }
     
    777788        else
    778789        {
     790            /* If this is the very first peek, make sure to *always* give back the peeking answer
     791             * instead of the actual command, even if this command would fit into the current
     792             * connection buffer. */
    779793            if (!mPeekCount)
    780794            {
  • trunk/src/VBox/Main/src-client/GuestProcessImpl.cpp

    r45482 r45697  
    736736
    737737    com::SafeArray<BYTE> data((size_t)dataCb.cbData);
    738     data.initFrom((BYTE*)dataCb.pvData, dataCb.cbData);
     738    if (dataCb.cbData)
     739        data.initFrom((BYTE*)dataCb.pvData, dataCb.cbData);
    739740
    740741    fireGuestProcessOutputEvent(mEventSource, mSession, this,
     
    755756    /* pcbRead is optional. */
    756757
    757     /** @todo Validate uHandle. */
    758 
    759758    AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    760759
    761     if (mData.mStatus != ProcessStatus_Started)
     760    if (   mData.mStatus != ProcessStatus_Started
     761        /* Skip reading if the process wasn't started with the appropriate
     762         * flags. */
     763        || (   (   uHandle == OUTPUT_HANDLE_ID_STDOUT
     764                || uHandle == OUTPUT_HANDLE_ID_STDOUT_DEPRECATED)
     765            && !(mData.mProcess.mFlags & ProcessCreateFlag_WaitForStdOut))
     766        || (   uHandle == OUTPUT_HANDLE_ID_STDERR
     767            && !(mData.mProcess.mFlags & ProcessCreateFlag_WaitForStdErr))
     768       )
    762769    {
    763770        if (pcbRead)
     
    780787        paParms[i++].setUInt32(0 /* Flags, none set yet. */);
    781788
     789        alock.release(); /* Drop the write lock before sending. */
     790
    782791        vrc = sendCommand(HOST_EXEC_GET_OUTPUT, i, paParms);
    783792    }
    784793
    785794    if (RT_SUCCESS(vrc))
    786     {
    787         alock.release(); /* Drop the write lock before waiting. */
    788 
    789795        vrc = waitForOutput(uHandle, uTimeoutMS,
    790796                            pvData, cbData, pcbRead);
    791     }
    792797
    793798    LogFlowFuncLeaveRC(vrc);
     
    904909        if (RT_SUCCESS(vrc))
    905910            vrc = mData.mProcess.mEnvironment.BuildEnvironmentBlock(&pvEnv, &cbEnv, NULL /* cEnv */);
     911
     912        uint32_t uTimeoutMS = mData.mProcess.mTimeoutMS;
    906913
    907914        if (RT_SUCCESS(vrc))
     
    939946                paParms[i++].setUInt32(UINT32_MAX /* Infinite timeout */);
    940947            else
    941                 paParms[i++].setUInt32(mData.mProcess.mTimeoutMS);
     948                paParms[i++].setUInt32(uTimeoutMS);
    942949            if (uProtocol >= 2)
    943950            {
     
    950957            }
    951958
     959            alock.release(); /* Drop the write lock before sending. */
     960
    952961            /* Note: Don't hold the write lock in here. */
    953962            vrc = sendCommand(HOST_EXEC_CMD, i, paParms);
     
    963972            RTStrFree(pszArgs);
    964973
    965         uint32_t uTimeoutMS = mData.mProcess.mTimeoutMS;
    966 
    967         /* Drop the write lock again before waiting. */
    968         alock.release();
    969 
    970974        if (RT_SUCCESS(vrc))
    971975        {
    972             vrc = waitForStatusChange(ProcessWaitForFlag_Start, 30 * 1000 /* Timeout */,
     976            vrc = waitForStatusChange(ProcessWaitForFlag_Start, uTimeoutMS,
    973977                                      NULL /* Process status */, pGuestRc);
    974978        }
     
    10551059        paParms[i++].setUInt32(mData.mPID);
    10561060
     1061        alock.release(); /* Drop the write lock before sending. */
     1062
    10571063        vrc = sendCommand(HOST_EXEC_TERMINATE, i, paParms);
    10581064    }
    10591065
    10601066    if (RT_SUCCESS(vrc))
    1061     {
    1062         alock.release(); /* Drop the write lock before waiting. */
    1063 
    10641067        vrc = waitForStatusChange(ProcessWaitForFlag_Terminate,
    10651068                                  30 * 1000 /* 30s timeout */,
    10661069                                  NULL /* ProcessStatus */, pGuestRc);
    1067     }
    1068 
    10691070    LogFlowFuncLeaveRC(vrc);
    10701071    return vrc;
     
    12671268    if (SUCCEEDED(hr))
    12681269    {
    1269         LogFlowThisFunc(("Waiting for guest file event(s) (timeout=%RU32ms, %zu events) ...\n",
     1270        LogFlowThisFunc(("Waiting for guest process event(s) (timeout=%RU32ms, %zu events) ...\n",
    12701271                         uTimeoutMS, arrEventTypes.size()));
    12711272
     
    14271428                    ComAssertComRC(hr);
    14281429                    size_t cbRead = data.size();
    1429                     if (   cbRead
    1430                         && cbRead <= cbData)
     1430                    if (cbRead)
    14311431                    {
    1432                         memcpy(pvData, data.raw(), data.size());
     1432                        if (cbRead <= cbData)
     1433                        {
     1434                            /* Copy data from event into our buffer. */
     1435                            memcpy(pvData, data.raw(), data.size());
     1436                        }
     1437                        else
     1438                            vrc = VERR_BUFFER_OVERFLOW;
    14331439                    }
    1434                     else
    1435                         vrc = VERR_BUFFER_OVERFLOW;
    14361440                }
    14371441                if (pcbRead)
    14381442                {
    1439                     hr = pProcessEvent->COMGETTER(Processed)((ULONG*)pcbRead);
     1443                    ULONG cbRead;
     1444                    hr = pProcessEvent->COMGETTER(Processed)(&cbRead);
    14401445                    ComAssertComRC(hr);
     1446                    *pcbRead = (uint32_t)cbRead;
    14411447                }
    14421448
     
    15251531        paParms[i++].setUInt32(cbData);
    15261532
     1533        alock.release(); /* Drop the write lock before sending. */
     1534
    15271535        vrc = sendCommand(HOST_EXEC_SET_INPUT, i, paParms);
    15281536    }
     
    15301538    if (RT_SUCCESS(vrc))
    15311539    {
    1532         alock.release(); /* Drop the write lock before waiting. */
    1533 
    15341540        ProcessInputStatus_T inputStatus;
    15351541        uint32_t cbProcessed;
     
    15931599    }
    15941600
    1595     LogFlowThisFunc(("rc=%Rrc, cbRead=%RU64\n", vrc, cbRead));
     1601    LogFlowThisFunc(("rc=%Rrc, cbRead=%RU32\n", vrc, cbRead));
    15961602
    15971603    LogFlowFuncLeaveRC(vrc);
     
    17361742    if (FAILED(autoCaller.rc())) return autoCaller.rc();
    17371743
     1744    com::SafeArray<BYTE> data(ComSafeArrayInArg(aData));
     1745
    17381746    HRESULT hr = S_OK;
    17391747
    1740     com::SafeArray<BYTE> data(ComSafeArrayInArg(aData)); int guestRc;
    1741     int vrc = writeData(aHandle, aFlags, data.raw(), data.size(), aTimeoutMS, (uint32_t*)aWritten, &guestRc);
     1748    uint32_t cbWritten; int guestRc;
     1749    int vrc = writeData(aHandle, aFlags, data.raw(), data.size(), aTimeoutMS, &cbWritten, &guestRc);
    17421750    if (RT_FAILURE(vrc))
    17431751    {
     
    17561764    }
    17571765
    1758     LogFlowThisFunc(("rc=%Rrc, aWritten=%RU32\n", vrc, aWritten));
     1766    LogFlowThisFunc(("rc=%Rrc, aWritten=%RU32\n", vrc, cbWritten));
     1767
     1768    *aWritten = (ULONG)cbWritten;
    17591769
    17601770    LogFlowFuncLeaveRC(vrc);
  • trunk/src/VBox/Main/src-client/GuestSessionImpl.cpp

    r45434 r45697  
    13581358                         pCurProc->getObjectID(), mData.mSession.mID, uPID, mData.mProcesses.size() - 1, mData.mNumObjects - 1));
    13591359
    1360             LogFlowFunc(("1\n"));
    13611360            mData.mProcesses.erase(itProcs);
    13621361            mData.mNumObjects--;
    13631362
    1364             LogFlowFunc(("2\n"));
    13651363            fireGuestProcessRegisteredEvent(mEventSource, this /* Session */, NULL /* Process */,
    13661364                                            uPID, false /* Process unregistered */);
    1367             LogFlowFunc(("3\n"));
    13681365            rc = VINF_SUCCESS;
    13691366            break;
    13701367        }
    13711368
    1372         LogFlowFunc(("4\n"));
    13731369        itProcs++;
    13741370    }
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