VirtualBox

Ignore:
Timestamp:
Jun 2, 2017 8:27:45 AM (8 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
115913
Message:

IPRT: vfsprogress.cpp: Added RTVFSPROGRESS_F_ALLOW_CANCEL for some kind of cancellation support.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/vfs/vfsprogress.cpp

    r67221 r67224  
    4848typedef struct RTVFSPROGRESSFILE
    4949{
     50    /** This is negative (RT_FAILURE) if canceled.  */
     51    int             rcCanceled;
    5052    /** RTVFSPROGRESS_F_XXX. */
    5153    uint32_t        fFlags;
     
    7880 * Update the progress and do the progress callback if necessary.
    7981 *
     82 * @returns Callback return code.
    8083 * @param   pThis     The file progress instance.
    8184 */
    82 static void rtVfsProgressFile_UpdateProgress(PRTVFSPROGRESSFILE pThis)
     85static int rtVfsProgressFile_UpdateProgress(PRTVFSPROGRESSFILE pThis)
    8386{
    8487    uint64_t cbDone = RT_MIN(pThis->cbCurrentlyRead, pThis->cbExpectedRead)
     
    8689    unsigned uPct = cbDone / pThis->cbExpected;
    8790    if (uPct == pThis->uCurPct)
    88         return;
     91        return pThis->rcCanceled;
    8992    pThis->uCurPct = uPct;
    90     pThis->pfnProgress(uPct, pThis->pvUser);
    91     /* Yes, we ignore the return code. */
     93
     94    int rc = pThis->pfnProgress(uPct, pThis->pvUser);
     95    if (!(pThis->fFlags & RTVFSPROGRESS_F_ALLOW_CANCEL))
     96        rc = VINF_SUCCESS;
     97    else if (RT_FAILURE(rc) && RT_SUCCESS(pThis->rcCanceled))
     98        pThis->rcCanceled = rc;
     99
     100    return rc;
    92101}
    93102
     
    120129{
    121130    PRTVFSPROGRESSFILE pThis = (PRTVFSPROGRESSFILE)pvThis;
    122     return RTVfsIoStrmQueryInfo(pThis->hVfsIos, pObjInfo, enmAddAttr);
     131    int rc = pThis->rcCanceled;
     132    if (RT_SUCCESS(rc))
     133        rc = RTVfsIoStrmQueryInfo(pThis->hVfsIos, pObjInfo, enmAddAttr);
     134    return rc;
    123135}
    124136
     
    131143    PRTVFSPROGRESSFILE pThis = (PRTVFSPROGRESSFILE)pvThis;
    132144
    133     /* Simplify a little there if a seeks is implied and assume the read goes well. */
    134     if (   off >= 0
    135         && (pThis->fFlags & RTVFSPROGRESS_F_FORWARD_SEEK_AS_READ))
    136     {
    137         uint64_t offCurrent = RTVfsFileTell(pThis->hVfsFile);
    138         if (offCurrent < (uint64_t)off)
    139             pThis->cbCurrentlyRead += off - offCurrent;
    140     }
    141 
    142     /* Calc the request before calling down the stack. */
    143     size_t   cbReq = 0;
    144     unsigned i = pSgBuf->cSegs;
    145     while (i-- > 0)
    146         cbReq += pSgBuf->paSegs[i].cbSeg;
    147 
    148     /* Do the read. */
    149     int rc = RTVfsIoStrmSgRead(pThis->hVfsIos, off, pSgBuf, fBlocking, pcbRead);
    150     if (RT_SUCCESS(rc))
    151     {
    152         /* Update the progress (we cannot cancel here, sorry). */
    153         pThis->cbCurrentlyRead += pcbRead ? *pcbRead : cbReq;
    154         rtVfsProgressFile_UpdateProgress(pThis);
     145    int rc = pThis->rcCanceled;
     146    if (RT_SUCCESS(rc))
     147    {
     148        /* Simplify a little there if a seeks is implied and assume the read goes well. */
     149        if (   off >= 0
     150            && (pThis->fFlags & RTVFSPROGRESS_F_FORWARD_SEEK_AS_READ))
     151        {
     152            uint64_t offCurrent = RTVfsFileTell(pThis->hVfsFile);
     153            if (offCurrent < (uint64_t)off)
     154                pThis->cbCurrentlyRead += off - offCurrent;
     155        }
     156
     157        /* Calc the request before calling down the stack. */
     158        size_t   cbReq = 0;
     159        unsigned i = pSgBuf->cSegs;
     160        while (i-- > 0)
     161            cbReq += pSgBuf->paSegs[i].cbSeg;
     162
     163        /* Do the read. */
     164        rc = RTVfsIoStrmSgRead(pThis->hVfsIos, off, pSgBuf, fBlocking, pcbRead);
     165        if (RT_SUCCESS(rc))
     166        {
     167            /* Update the progress (we cannot cancel here, sorry). */
     168            pThis->cbCurrentlyRead += pcbRead ? *pcbRead : cbReq;
     169            rtVfsProgressFile_UpdateProgress(pThis);
     170        }
    155171    }
    156172
     
    166182    PRTVFSPROGRESSFILE pThis = (PRTVFSPROGRESSFILE)pvThis;
    167183
    168     /* Simplify a little there if a seeks is implied and assume the write goes well. */
    169     if (   off >= 0
    170         && (pThis->fFlags & RTVFSPROGRESS_F_FORWARD_SEEK_AS_WRITE))
    171     {
    172         uint64_t offCurrent = RTVfsFileTell(pThis->hVfsFile);
    173         if (offCurrent < (uint64_t)off)
    174             pThis->cbCurrentlyWritten += off - offCurrent;
    175     }
    176 
    177     /* Calc the request before calling down the stack. */
    178     size_t   cbReq = 0;
    179     unsigned i = pSgBuf->cSegs;
    180     while (i-- > 0)
    181         cbReq += pSgBuf->paSegs[i].cbSeg;
    182 
    183     /* Do the read. */
    184     int rc = RTVfsIoStrmSgWrite(pThis->hVfsIos, off, pSgBuf, fBlocking, pcbWritten);
    185     if (RT_SUCCESS(rc))
    186     {
    187         /* Update the progress (we cannot cancel here, sorry). */
    188         pThis->cbCurrentlyWritten += pcbWritten ? *pcbWritten : cbReq;
    189         rtVfsProgressFile_UpdateProgress(pThis);
     184    int rc = pThis->rcCanceled;
     185    if (RT_SUCCESS(rc))
     186    {
     187        /* Simplify a little there if a seeks is implied and assume the write goes well. */
     188        if (   off >= 0
     189            && (pThis->fFlags & RTVFSPROGRESS_F_FORWARD_SEEK_AS_WRITE))
     190        {
     191            uint64_t offCurrent = RTVfsFileTell(pThis->hVfsFile);
     192            if (offCurrent < (uint64_t)off)
     193                pThis->cbCurrentlyWritten += off - offCurrent;
     194        }
     195
     196        /* Calc the request before calling down the stack. */
     197        size_t   cbReq = 0;
     198        unsigned i = pSgBuf->cSegs;
     199        while (i-- > 0)
     200            cbReq += pSgBuf->paSegs[i].cbSeg;
     201
     202        /* Do the read. */
     203        rc = RTVfsIoStrmSgWrite(pThis->hVfsIos, off, pSgBuf, fBlocking, pcbWritten);
     204        if (RT_SUCCESS(rc))
     205        {
     206            /* Update the progress (we cannot cancel here, sorry). */
     207            pThis->cbCurrentlyWritten += pcbWritten ? *pcbWritten : cbReq;
     208            rtVfsProgressFile_UpdateProgress(pThis);
     209        }
    190210    }
    191211
     
    200220{
    201221    PRTVFSPROGRESSFILE pThis = (PRTVFSPROGRESSFILE)pvThis;
    202     return RTVfsIoStrmFlush(pThis->hVfsIos);
     222    int rc = pThis->rcCanceled;
     223    if (RT_SUCCESS(rc))
     224        rc = RTVfsIoStrmFlush(pThis->hVfsIos);
     225    return rc;
    203226}
    204227
     
    211234{
    212235    PRTVFSPROGRESSFILE pThis = (PRTVFSPROGRESSFILE)pvThis;
    213     return RTVfsIoStrmPoll(pThis->hVfsIos, fEvents, cMillies, fIntr, pfRetEvents);
     236    int rc = pThis->rcCanceled;
     237    if (RT_SUCCESS(rc))
     238        rc = RTVfsIoStrmPoll(pThis->hVfsIos, fEvents, cMillies, fIntr, pfRetEvents);
     239    else
     240    {
     241        *pfRetEvents |= RTPOLL_EVT_ERROR;
     242        rc = VINF_SUCCESS;
     243    }
     244    return rc;
    214245}
    215246
     
    232263{
    233264    PRTVFSPROGRESSFILE pThis = (PRTVFSPROGRESSFILE)pvThis;
    234     int rc = RTVfsIoStrmSkip(pThis->hVfsIos, cb);
    235     if (RT_SUCCESS(rc))
    236     {
    237         pThis->cbCurrentlyRead += cb;
    238         rtVfsProgressFile_UpdateProgress(pThis);
     265    int rc = pThis->rcCanceled;
     266    if (RT_SUCCESS(rc))
     267    {
     268        rc = RTVfsIoStrmSkip(pThis->hVfsIos, cb);
     269        if (RT_SUCCESS(rc))
     270        {
     271            pThis->cbCurrentlyRead += cb;
     272            rtVfsProgressFile_UpdateProgress(pThis);
     273        }
    239274    }
    240275    return rc;
     
    248283{
    249284    PRTVFSPROGRESSFILE pThis = (PRTVFSPROGRESSFILE)pvThis;
    250     int rc = RTVfsIoStrmZeroFill(pThis->hVfsIos, cb);
    251     if (RT_SUCCESS(rc))
    252     {
    253         pThis->cbCurrentlyWritten += cb;
    254         rtVfsProgressFile_UpdateProgress(pThis);
     285    int rc = pThis->rcCanceled;
     286    if (RT_SUCCESS(rc))
     287    {
     288        rc = RTVfsIoStrmZeroFill(pThis->hVfsIos, cb);
     289        if (RT_SUCCESS(rc))
     290        {
     291            pThis->cbCurrentlyWritten += cb;
     292            rtVfsProgressFile_UpdateProgress(pThis);
     293        }
    255294    }
    256295    return rc;
     
    424463    if (RT_SUCCESS(rc))
    425464    {
     465        pThis->rcCanceled           = VINF_SUCCESS;
    426466        pThis->fFlags               = fFlags;
    427467        pThis->pfnProgress          = pfnProgress;
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