VirtualBox

Changeset 19562 in vbox for trunk/src/VBox/Runtime/r3/posix


Ignore:
Timestamp:
May 10, 2009 9:44:16 PM (16 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
47117
Message:

Runtime/Aio: Change API again

  • pcReqs in RTFileAioCtxSubmit is useless because it does not specify which request fails. Removed it again and made it possible to get the state of a request through RTFileAioReqGetRC()
  • Introduce request states for the first point and to catch more errors using the API before a system dependent call is made to return the same error codes one every system for the same cause.
  • Add RTFileAioGetLimits to get global limits and indication for AIO support.
  • General cleanups and fixes
File:
1 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/r3/posix/fileaio-posix.cpp

    r19370 r19562  
    4545#include "internal/fileaio.h"
    4646
     47#if defined(RT_OS_DARWIN)
     48# include <sys/types.h>
     49# include <sys/sysctl.h> /* for sysctlbyname */
     50#endif
    4751#include <aio.h>
    4852#include <errno.h>
     
    7074    /** Next element in the chain. */
    7175    struct RTFILEAIOREQINTERNAL *pNext;
     76    /** Previous element in the chain. */
     77    struct RTFILEAIOREQINTERNAL *pPrev;
     78    /** Current state the request is in. */
     79    RTFILEAIOREQSTATE            enmState;
    7280    /** Flag whether this is a flush request. */
    7381    bool                         fFlush;
     
    183191                pReqHead = pReqHead->pNext;
    184192
    185                 /* Clear pointer to next element just for safety. */
     193                /* Clear pointer to next and previous element just for safety. */
    186194                pCtxInt->apReqs[pCtxInt->iFirstFree]->pNext = NULL;
     195                pCtxInt->apReqs[pCtxInt->iFirstFree]->pPrev = NULL;
    187196                pCtxInt->iFirstFree++;
    188197                Assert(pCtxInt->iFirstFree <= pCtxInt->cMaxRequests);
     
    210219}
    211220
     221RTR3DECL(int) RTFileAioGetLimits(PRTFILEAIOLIMITS pAioLimits)
     222{
     223    int rcBSD = 0;
     224    AssertPtrReturn(pAioLimits, VERR_INVALID_POINTER);
     225
     226#if defined(RT_OS_DARWIN)
     227    int cReqsOutstandingMax = 0;
     228    size_t cbParameter = sizeof(int);
     229
     230    rcBSD = sysctlbyname("kern.aioprocmax",     /* name */
     231                         &cReqsOutstandingMax,  /* Where to store the old value. */
     232                         &cbParameter,          /* Size of the memory pointed to. */
     233                         NULL,                  /* Where the new value is located. */
     234                         NULL);                 /* Where the size of the new value is stored. */
     235    if (rcBSD == -1)
     236        return RTErrConvertFromErrno(errno);
     237
     238    pAioLimits->cReqsOutstandingMax = cReqsOutstandingMax;
     239    pAioLimits->cbBufferAlignment   = 0;
     240#else
     241    pAioLimits->cReqsOutstandingMax = RTFILEAIO_UNLIMITED_REQS;
     242    pAioLimits->cbBufferAlignment   = 0;
     243#endif
     244
     245    return VINF_SUCCESS;
     246}
     247
    212248RTR3DECL(int) RTFileAioReqCreate(PRTFILEAIOREQ phReq)
    213249{
     
    220256    pReqInt->pCtxInt  = NULL;
    221257    pReqInt->u32Magic = RTFILEAIOREQ_MAGIC;
     258    RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
    222259
    223260    *phReq = (RTFILEAIOREQ)pReqInt;
     
    227264
    228265
    229 RTDECL(void) RTFileAioReqDestroy(RTFILEAIOREQ hReq)
     266RTDECL(int) RTFileAioReqDestroy(RTFILEAIOREQ hReq)
    230267{
    231268    /*
     
    233270     */
    234271    if (hReq == NIL_RTFILEAIOREQ)
    235         return;
     272        return VINF_SUCCESS;
    236273    PRTFILEAIOREQINTERNAL pReqInt = hReq;
    237     RTFILEAIOREQ_VALID_RETURN_VOID(pReqInt);
     274    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     275    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
    238276
    239277    /*
     
    242280    ASMAtomicUoWriteU32(&pReqInt->u32Magic, ~RTFILEAIOREQ_MAGIC);
    243281    RTMemFree(pReqInt);
     282    return VINF_SUCCESS;
    244283}
    245284
     
    257296    PRTFILEAIOREQINTERNAL pReqInt = hReq;
    258297    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     298    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
    259299    Assert(hFile != NIL_RTFILE);
    260300    AssertPtr(pvBuf);
     
    271311    pReqInt->pCtxInt              = NULL;
    272312    pReqInt->Rc                   = VERR_FILE_AIO_IN_PROGRESS;
     313    RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED);
    273314
    274315    return VINF_SUCCESS;
     
    297338
    298339    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     340    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
    299341    Assert(hFile != NIL_RTFILE);
    300342
     
    302344    pReqInt->AioCB.aio_fildes = (int)hFile;
    303345    pReqInt->pvUser           = pvUser;
     346    RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED);
    304347
    305348    return VINF_SUCCESS;
     
    320363    PRTFILEAIOREQINTERNAL pReqInt = hReq;
    321364    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     365    RTFILEAIOREQ_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_NOT_SUBMITTED);
    322366
    323367    ASMAtomicXchgBool(&pReqInt->fCanceled, true);
     
    343387
    344388        ASMAtomicWritePtr((void* volatile*)&pCtxInt->pReqToCancel, NULL);
     389        pReqInt->Rc = VERR_FILE_AIO_CANCELED;
     390        RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
    345391        return VINF_SUCCESS;
    346392    }
     
    358404    PRTFILEAIOREQINTERNAL pReqInt = hReq;
    359405    RTFILEAIOREQ_VALID_RETURN(pReqInt);
     406    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, SUBMITTED, VERR_FILE_AIO_IN_PROGRESS);
     407    RTFILEAIOREQ_NOT_STATE_RETURN_RC(pReqInt, PREPARED, VERR_FILE_AIO_NOT_SUBMITTED);
    360408    AssertPtrNull(pcbTransfered);
    361409
    362     if (  (pReqInt->Rc != VERR_FILE_AIO_IN_PROGRESS)
     410    if (  (RT_SUCCESS(pReqInt->Rc))
    363411        && (pcbTransfered))
    364412        *pcbTransfered = pReqInt->cbTransfered;
     
    425473}
    426474
    427 RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs, size_t *pcReqs)
     475RTDECL(int) RTFileAioCtxSubmit(RTFILEAIOCTX hAioCtx, PRTFILEAIOREQ pahReqs, size_t cReqs)
    428476{
    429477    int rc = VINF_SUCCESS;
     
    452500        {
    453501            pReqInt = pahReqs[i];
    454             RTFILEAIOREQ_VALID_RETURN(pReqInt);
     502            if (RTFILEAIOREQ_IS_NOT_VALID(pReqInt))
     503            {
     504                /* Undo everything and stop submitting. */
     505                for (size_t iUndo = 0; iUndo < i; iUndo++)
     506                {
     507                    pReqInt = pahReqs[iUndo];
     508                    RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED);
     509                    pReqInt->pCtxInt = NULL;
     510
     511                    /* Unlink from the list again. */
     512                    PRTFILEAIOREQINTERNAL pNext, pPrev;
     513                    pNext = pReqInt->pNext;
     514                    pPrev = pReqInt->pPrev;
     515                    if (pNext)
     516                        pNext->pPrev = pPrev;
     517                    if (pPrev)
     518                        pPrev->pNext = pNext;
     519                    else
     520                        pHead = pNext;
     521                }
     522                rc = VERR_INVALID_HANDLE;
     523                break;
     524            }
    455525
    456526            pReqInt->pCtxInt = pCtxInt;
     
    458528            /* Link them together. */
    459529            pReqInt->pNext = pHead;
     530            if (pHead)
     531                pHead->pPrev = pReqInt;
     532            pReqInt->pPrev = NULL;
    460533            pHead = pReqInt;
     534            RTFILEAIOREQ_SET_STATE(pReqInt, SUBMITTED);
    461535
    462536            if (pReqInt->fFlush)
     
    472546            if (RT_UNLIKELY(rcPosix < 0))
    473547            {
    474                 rc = RTErrConvertFromErrno(errno);
     548                if (rcPosix == EAGAIN)
     549                    rc = VERR_FILE_AIO_INSUFFICIENT_RESSOURCES;
     550                else
     551                    rc = RTErrConvertFromErrno(errno);
     552
     553                /* Check which ones were not submitted. */
     554                for (i = 0; i < cReqs; i++)
     555                {
     556                    pReqInt = pahReqs[i];
     557                    rcPosix = aio_error(&pReqInt->AioCB);
     558                    if (rcPosix != EINPROGRESS)
     559                    {
     560                        if (rcPosix == EINVAL)
     561                        {
     562                            /* Was not submitted. */
     563                            RTFILEAIOREQ_SET_STATE(pReqInt, PREPARED);
     564                        }
     565                        else
     566                        {
     567                            /* An error occured. */
     568                            RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
     569                            pReqInt->Rc = RTErrConvertFromErrno(rcPosix);
     570                            pReqInt->cbTransfered = 0;
     571                        }
     572                        /* Unlink from the list. */
     573                        PRTFILEAIOREQINTERNAL pNext, pPrev;
     574                        pNext = pReqInt->pNext;
     575                        pPrev = pReqInt->pPrev;
     576                        if (pNext)
     577                            pNext->pPrev = pPrev;
     578                        if (pPrev)
     579                            pPrev->pNext = pNext;
     580                        else
     581                            pHead = pNext;
     582                    }
     583                }
     584
    475585                break;
    476586            }
     
    479589            cReqs   -= cReqsSubmit;
    480590            pahReqs += cReqsSubmit;
    481             *pcReqs += cReqsSubmit;
    482591        }
    483592
     
    488597            RTFILEAIOREQ_VALID_RETURN(pReqInt);
    489598
    490             if (pReqInt->fFlush)
     599            Assert(pReqInt->fFlush);
     600
     601            /*
     602             * lio_listio does not work with flush requests so
     603             * we have to use aio_fsync directly.
     604             */
     605            rcPosix = aio_fsync(O_SYNC, &pReqInt->AioCB);
     606            if (RT_UNLIKELY(rcPosix < 0))
    491607            {
    492                 /*
    493                  * lio_listio does not work with flush requests so
    494                  * we have to use aio_fsync directly.
    495                  */
    496                  rcPosix = aio_fsync(O_SYNC, &pReqInt->AioCB);
    497                  if (RT_UNLIKELY(rcPosix < 0))
    498                  {
    499                     rc = RTErrConvertFromErrno(errno);
    500                     break;
    501                  }
    502 
    503                 ASMAtomicIncS32(&pCtxInt->cRequests);
    504                 cReqs--;
    505                 pahReqs++;
    506                 *pcReqs++;
     608                rc = RTErrConvertFromErrno(errno);
     609                RTFILEAIOREQ_SET_STATE(pReqInt, COMPLETED);
     610                pReqInt->Rc = rc;
     611                pReqInt->cbTransfered = 0;
     612
     613                /* Unlink from the list. */
     614                PRTFILEAIOREQINTERNAL pNext, pPrev;
     615                pNext = pReqInt->pNext;
     616                pPrev = pReqInt->pPrev;
     617                if (pNext)
     618                    pNext->pPrev = pPrev;
     619                if (pPrev)
     620                    pPrev->pNext = pNext;
     621                else
     622                    pHead = pNext;
     623                break;
    507624            }
     625
     626            ASMAtomicIncS32(&pCtxInt->cRequests);
     627            cReqs--;
     628            pahReqs++;
    508629        }
    509630    } while (cReqs);
     
    625746                        pReq->Rc = RTErrConvertFromErrno(rcReq);
    626747
     748                    /* Mark the request as finished. */
     749                    RTFILEAIOREQ_SET_STATE(pReq, COMPLETED);
    627750                    cDone++;
    628751
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