VirtualBox

Changeset 67224 in vbox for trunk


Ignore:
Timestamp:
Jun 2, 2017 8:27:45 AM (7 years ago)
Author:
vboxsync
Message:

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

Location:
trunk
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/include/iprt/vfs.h

    r67223 r67224  
    13121312 * @param   hVfsIos             The I/O stream to wrap.
    13131313 * @param   pfnProgress         The progress callback.  The return code is
    1314  *                              ignored!
     1314 *                              ignored by default, but can be enabled using
     1315 *                              RTVFSPROGRESS_F_ALLOW_CANCEL.
    13151316 * @param   pvUser              The user argument to @a pfnProgress.
    13161317 * @param   fFlags              RTVFSPROGRESS_F_XXX
     
    13181319 * @param   cbExpectedWritten   The execpted number of bytes written.
    13191320 * @param   phVfsIos            Where to return the I/O stream handle.
    1320  *
    1321  * @remarks Again, the return code from @a pfnProgress is ignored.  Cancellation
    1322  *          is not supported.
    13231321 */
    13241322RTDECL(int) RTVfsCreateProcessForIoStream(RTVFSIOSTREAM hVfsIos, PFNRTPROGRESS pfnProgress, void *pvUser, uint32_t fFlags,
     
    13311329 * @param   hVfsFile            The file to wrap.
    13321330 * @param   pfnProgress         The progress callback.  The return code is
    1333  *                              ignored!
     1331 *                              ignored by default, but can be enabled using
     1332 *                              RTVFSPROGRESS_F_ALLOW_CANCEL.
    13341333 * @param   pvUser              The user argument to @a pfnProgress.
    13351334 * @param   fFlags              RTVFSPROGRESS_F_XXX
     
    13371336 * @param   cbExpectedWritten   The execpted number of bytes written.
    13381337 * @param   phVfsFile           Where to return the file handle.
    1339  *
    1340  * @remarks Again, the return code from @a pfnProgress is ignored.  Cancellation
    1341  *          is not supported.
    13421338 */
    13431339RTDECL(int) RTVfsCreateProcessForFile(RTVFSFILE hVfsFile, PFNRTPROGRESS pfnProgress, void *pvUser, uint32_t fFlags,
     
    13471343 *        RTVfsCreateProcessForFile.
    13481344 * @{ */
     1345/** Allow cancellation, forcing every access to return the pfnProgress failure
     1346 * status triggering it.  The cancelation is generally delayed till the next
     1347 * operation after the cancel was seen. */
     1348#define RTVFSPROGRESS_F_ALLOW_CANCEL            RT_BIT_32(0)
    13491349/** Account forward seeks as reads. */
    1350 #define RTVFSPROGRESS_F_FORWARD_SEEK_AS_READ    RT_BIT_32(0)
     1350#define RTVFSPROGRESS_F_FORWARD_SEEK_AS_READ    RT_BIT_32(1)
    13511351/** Account fprward seeks as writes. */
    1352 #define RTVFSPROGRESS_F_FORWARD_SEEK_AS_WRITE   RT_BIT_32(1)
     1352#define RTVFSPROGRESS_F_FORWARD_SEEK_AS_WRITE   RT_BIT_32(2)
    13531353/** Valid bits.   */
    1354 #define RTVFSPROGRESS_F_VALID_MASK              UINT32_C(0x00000003)
     1354#define RTVFSPROGRESS_F_VALID_MASK              UINT32_C(0x00000007)
    13551355/** @} */
    13561356
  • 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.

© 2024 Oracle Support Privacy / Do Not Sell My Info Terms of Use Trademark Policy Automated Access Etiquette