VirtualBox

Changeset 28943 in vbox


Ignore:
Timestamp:
Apr 30, 2010 3:47:23 PM (15 years ago)
Author:
vboxsync
Message:

Guest Control/Main/VBoxService: Update on locking, bugfixes.

Location:
trunk/src/VBox
Files:
4 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceControlExec.cpp

    r28926 r28943  
    535535}
    536536
     537int VBoxServiceControlExecInitPipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf)
     538{
     539    AssertPtr(pBuf);
     540
     541    pBuf->pbData = (uint8_t*)RTMemAlloc(_64K); /* Start with a 64k buffer. */
     542    AssertReturn(pBuf->pbData, VERR_NO_MEMORY);
     543    pBuf->cbSize = 0;
     544    pBuf->cbOffset = 0;
     545    pBuf->cbRead = 0;
     546
     547    return RTSemMutexCreate(&pBuf->mtx);
     548}
     549
     550int VBoxServiceControlExecDestroyPipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf)
     551{
     552    if (pBuf)
     553    {
     554        if (pBuf->pbData)
     555            RTMemFree(pBuf->pbData);
     556        pBuf->pbData = NULL;
     557        pBuf->cbSize = 0;
     558        pBuf->cbOffset = 0;
     559        pBuf->cbRead = 0;
     560    }
     561    return RTSemMutexDestroy(pBuf->mtx);
     562}
     563
    537564int VBoxServiceControlExecReadPipeBufferContent(PVBOXSERVICECTRLEXECPIPEBUF pBuf,
    538565                                                uint8_t *pbBuffer, uint32_t cbBuffer, uint32_t *pcbToRead)
    539566{
     567    AssertPtr(pBuf);
    540568    AssertPtr(pcbToRead);
    541569
    542 // LOCKING
    543 
    544     Assert(pBuf->cbOffset >= pBuf->cbRead);
    545     if (*pcbToRead > pBuf->cbOffset - pBuf->cbRead)
    546         *pcbToRead = pBuf->cbOffset - pBuf->cbRead;
    547 
    548     if (*pcbToRead > cbBuffer)
    549         *pcbToRead = cbBuffer;
    550 
    551     if (*pcbToRead > 0)
    552     {
    553         memcpy(pbBuffer, pBuf->pbData + pBuf->cbRead, *pcbToRead);
    554         pBuf->cbRead += *pcbToRead;
    555     }
    556     else
    557     {
    558         pbBuffer = NULL;
    559         *pcbToRead = 0;
    560     }
    561     return VINF_SUCCESS;
     570    int rc = RTSemMutexRequest(pBuf->mtx, RT_INDEFINITE_WAIT);
     571    if (RT_SUCCESS(rc))
     572    {   
     573        Assert(pBuf->cbOffset >= pBuf->cbRead);
     574        if (*pcbToRead > pBuf->cbOffset - pBuf->cbRead)
     575            *pcbToRead = pBuf->cbOffset - pBuf->cbRead;
     576   
     577        if (*pcbToRead > cbBuffer)
     578            *pcbToRead = cbBuffer;
     579   
     580        if (*pcbToRead > 0)
     581        {
     582            memcpy(pbBuffer, pBuf->pbData + pBuf->cbRead, *pcbToRead);
     583            pBuf->cbRead += *pcbToRead;
     584        }
     585        else
     586        {
     587            pbBuffer = NULL;
     588            *pcbToRead = 0;
     589        }
     590        rc = RTSemMutexRelease(pBuf->mtx);
     591    }
     592    return rc;
    562593}
    563594
     
    567598    AssertPtr(pBuf);
    568599
    569 // LOCKING
    570 
    571     /** @todo Use RTMemCache or RTMemObj here? */
    572     uint8_t *pNewBuf;
    573     while (pBuf->cbSize - pBuf->cbOffset < cbData)
    574     {
    575         pNewBuf = (uint8_t*)RTMemRealloc(pBuf->pbData, pBuf->cbSize + _4K);
    576         if (pNewBuf == NULL)
    577             break;
    578         pBuf->cbSize += _4K;
    579         pBuf->pbData = pNewBuf;
    580     }
    581 
    582     int rc = VINF_SUCCESS;
    583     if (pBuf->pbData)
    584     {
    585         memcpy(pBuf->pbData + pBuf->cbOffset, pbData, cbData);
    586         pBuf->cbOffset += cbData;
    587         /** @todo Add offset clamping! */
    588     }
    589     else
    590         rc = VERR_NO_MEMORY;
     600    int rc = RTSemMutexRequest(pBuf->mtx, RT_INDEFINITE_WAIT);
     601    if (RT_SUCCESS(rc))
     602    {   
     603        /** @todo Use RTMemCache or RTMemObj here? */
     604        uint8_t *pNewBuf;
     605        while (pBuf->cbSize - pBuf->cbOffset < cbData)
     606        {
     607            pNewBuf = (uint8_t*)RTMemRealloc(pBuf->pbData, pBuf->cbSize + _4K);
     608            if (pNewBuf == NULL)
     609                break;
     610            pBuf->cbSize += _4K;
     611            pBuf->pbData = pNewBuf;
     612        }
     613       
     614        int rc = VINF_SUCCESS;
     615        if (pBuf->pbData)
     616        {
     617            memcpy(pBuf->pbData + pBuf->cbOffset, pbData, cbData);
     618            pBuf->cbOffset += cbData;
     619            /** @todo Add offset clamping! */
     620        }
     621        else
     622            rc = VERR_NO_MEMORY;
     623        int rc2 = RTSemMutexRelease(pBuf->mtx);
     624        if (RT_SUCCESS(rc))
     625            rc = rc2;
     626    }
    591627    return rc;
    592628}
     
    668704
    669705        /* Init buffers. */
    670         pData->stdOut.pbData = NULL;
    671         pData->stdOut.cbSize = 0;
    672         pData->stdOut.cbOffset = 0;
    673         pData->stdOut.cbRead = 0;
    674 
    675         pData->stdErr.pbData = NULL;
    676         pData->stdErr.cbSize = 0;
    677         pData->stdErr.cbOffset = 0;
    678         pData->stdErr.cbRead = 0;
     706        rc = VBoxServiceControlExecInitPipeBuffer(&pData->stdOut);
     707        if (RT_SUCCESS(rc))
     708            rc = VBoxServiceControlExecInitPipeBuffer(&pData->stdErr);
    679709    }
    680710
     
    689719    }
    690720    return rc;
    691 }
    692 
    693 void VBoxServiceControlExecDestroyPipeBuffer(PVBOXSERVICECTRLEXECPIPEBUF pBuf)
    694 {
    695     if (pBuf)
    696     {
    697         if (pBuf->pbData)
    698             RTMemFree(pBuf->pbData);
    699         pBuf->pbData = NULL;
    700         pBuf->cbSize = 0;
    701         pBuf->cbOffset = 0;
    702         pBuf->cbRead = 0;
    703     }
    704721}
    705722
  • trunk/src/VBox/Additions/common/VBoxService/VBoxServiceInternal.h

    r28800 r28943  
    2727#ifdef VBOX_WITH_GUEST_CONTROL
    2828# include <iprt/list.h>
     29# include <iprt/semaphore.h>
    2930#endif
    3031
     
    134135typedef struct
    135136{
    136     uint8_t  *pbData;
    137     uint32_t  cbSize;
    138     uint32_t  cbOffset;
    139     uint32_t  cbRead;
     137    uint8_t    *pbData;
     138    uint32_t    cbSize;
     139    uint32_t    cbOffset;
     140    uint32_t    cbRead;
     141    RTSEMMUTEX  mtx;
    140142} VBOXSERVICECTRLEXECPIPEBUF;
    141143/** Pointer to thread data. */
  • trunk/src/VBox/Frontends/VBoxManage/VBoxManageGuestCtrl.cpp

    r28926 r28943  
    344344                while (SUCCEEDED(progress->COMGETTER(Completed(&fCompleted))))
    345345                {
     346                    /*
     347                     * because we want to get all the output data even if the process
     348                     * already ended, we first need to check whether there is some data
     349                     * left to output before checking the actual timeout and is-process-completed
     350                     * stuff.
     351                     */
    346352                    if (cbOutputData <= 0)
    347353                    {
     
    382388                    }
    383389
    384                     /* process async cancelation. */
     390                    /* process async cancelation */
    385391                    if (g_fExecCanceled && !fCanceledAlready)
    386392                    {
     
    404410                }
    405411
    406                 /* Not completed yet? -> Timeout */
    407                 if (fCompleted)
    408                 {
    409                     LONG iRc = false;
    410                     CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
    411                     if (FAILED(iRc))
    412                     {
    413                         ComPtr<IVirtualBoxErrorInfo> execError;
    414                         rc = progress->COMGETTER(ErrorInfo)(execError.asOutParam());
    415                         com::ErrorInfo info (execError);
    416                         RTPrintf("\n\nProcess error details:\n");
    417                         GluePrintErrorInfo(info);
    418                         RTPrintf("\n");
    419                     }         
     412                BOOL fCanceled;
     413                CHECK_ERROR_RET(progress, COMGETTER(Canceled)(&fCanceled), rc);
     414                if (fCanceled)
     415                {
     416                    RTPrintf("Process execution canceled!\n");
    420417                }
    421418                else
    422                 {
    423                     RTPrintf("Process timed out!\n");
    424                 }
    425                
    426                 if (verbose)
    427                 {
    428                     ULONG uRetStatus, uRetExitCode, uRetFlags;
    429                     CHECK_ERROR_BREAK(guest, GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus));
    430                     RTPrintf("Exit code=%u (Status=%u, Flags=%u)\n", uRetExitCode, uRetStatus, uRetFlags);
     419                {                   
     420                    if (fCompleted)
     421                    {
     422                        LONG iRc = false;
     423                        CHECK_ERROR_RET(progress, COMGETTER(ResultCode)(&iRc), rc);
     424                        if (FAILED(iRc))
     425                        {
     426                            ComPtr<IVirtualBoxErrorInfo> execError;
     427                            rc = progress->COMGETTER(ErrorInfo)(execError.asOutParam());
     428                            com::ErrorInfo info (execError);
     429                            RTPrintf("\n\nProcess error details:\n");
     430                            GluePrintErrorInfo(info);
     431                            RTPrintf("\n");
     432                        }
     433                        if (verbose)
     434                        {
     435                            ULONG uRetStatus, uRetExitCode, uRetFlags;
     436                            CHECK_ERROR_BREAK(guest, GetProcessStatus(uPID, &uRetExitCode, &uRetFlags, &uRetStatus));
     437                            RTPrintf("Exit code=%u (Status=%u, Flags=%u)\n", uRetExitCode, uRetStatus, uRetFlags);
     438                        }       
     439                    }
     440                    else /* not completed yet? -> timeout */
     441                    {
     442                        RTPrintf("Process timed out!\n");
     443                    }
    431444                }
    432445            }
  • trunk/src/VBox/Main/GuestImpl.cpp

    r28926 r28943  
    462462    int rc = VINF_SUCCESS;
    463463
    464     AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
    465 
    466464    AssertPtr(pData);
    467465    CallbackListIter it = getCtrlCallbackContextByID(pData->hdr.u32ContextID);
     
    470468    if (it != mCallbackList.end())
    471469    {
     470        AutoWriteLock alock(this COMMA_LOCKVAL_SRC_POS);
     471
    472472        PHOSTEXECCALLBACKDATA pCBData = (HOSTEXECCALLBACKDATA*)it->pvData;
    473473        AssertPtr(pCBData);
     
    655655            && !it->pProgress->getCompleted())
    656656        {
    657             it->pProgress->notifyComplete(S_OK);
     657            /* Only notify as complete if not canceled! */
     658            BOOL fCancelled;
     659            if (SUCCEEDED(it->pProgress->COMGETTER(Canceled)(&fCancelled)) && !fCancelled)
     660                it->pProgress->notifyComplete(S_OK);
    658661            it->pProgress = NULL;
    659662        }
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