VirtualBox

Changeset 60121 in vbox for trunk/src/VBox


Ignore:
Timestamp:
Mar 21, 2016 2:28:23 PM (9 years ago)
Author:
vboxsync
Message:

RTReqQueueProcess: Addressed todo regarding lost requests and document behavior more accuratly.

Location:
trunk/src/VBox/Runtime
Files:
2 edited

Legend:

Unmodified
Added
Removed
  • trunk/src/VBox/Runtime/common/misc/reqqueue.cpp

    r57358 r60121  
    109109
    110110    /*
    111      * Process loop.
    112      *
    113      * We do not repeat the outer loop if we've got an informational status code
    114      * since that code needs processing by our caller.
     111     * Process loop.  Stop (break) after the first non-VINF_SUCCESS status code.
    115112     */
    116113    int rc = VINF_SUCCESS;
    117     while (rc <= VINF_SUCCESS)
    118114    {
    119115        /*
    120116         * Get pending requests.
    121117         */
    122         PRTREQ pReqs = ASMAtomicXchgPtrT(&pQueue->pReqs, NULL, PRTREQ);
    123         if (!pReqs)
     118        PRTREQ pReqs = ASMAtomicXchgPtrT(&pQueue->pAlreadyPendingReqs, NULL, PRTREQ);
     119        if (RT_LIKELY(!pReqs))
    124120        {
    125             ASMAtomicWriteBool(&pQueue->fBusy, false); /* this aint 100% perfect, but it's good enough for now... */
    126             /** @todo We currently don't care if the entire time wasted here is larger than
    127              *        cMillies */
    128             rc = RTSemEventWait(pQueue->EventSem, cMillies);
    129             if (rc != VINF_SUCCESS)
    130                 break;
    131             continue;
     121            PRTREQ pReqs = ASMAtomicXchgPtrT(&pQueue->pReqs, NULL, PRTREQ);
     122            if (!pReqs)
     123            {
     124                /* We do not adjust cMillies (documented behavior). */
     125                ASMAtomicWriteBool(&pQueue->fBusy, false); /* this aint 100% perfect, but it's good enough for now... */
     126                rc = RTSemEventWait(pQueue->EventSem, cMillies);
     127                if (rc != VINF_SUCCESS)
     128                    break;
     129                continue;
     130            }
     131
     132            ASMAtomicWriteBool(&pQueue->fBusy, true);
     133
     134            /*
     135             * Reverse the list to process it in FIFO order.
     136             */
     137            PRTREQ pReq = pReqs;
     138            if (pReq->pNext)
     139                Log2(("RTReqQueueProcess: 2+ requests: %p %p %p\n", pReq, pReq->pNext, pReq->pNext->pNext));
     140            pReqs = NULL;
     141            while (pReq)
     142            {
     143                Assert(pReq->enmState == RTREQSTATE_QUEUED);
     144                Assert(pReq->uOwner.hQueue == pQueue);
     145                PRTREQ pCur = pReq;
     146                pReq = pReq->pNext;
     147                pCur->pNext = pReqs;
     148                pReqs = pCur;
     149            }
     150
    132151        }
    133         ASMAtomicWriteBool(&pQueue->fBusy, true);
    134 
    135         /*
    136          * Reverse the list to process it in FIFO order.
    137          */
    138         PRTREQ pReq = pReqs;
    139         if (pReq->pNext)
    140             Log2(("RTReqQueueProcess: 2+ requests: %p %p %p\n", pReq, pReq->pNext, pReq->pNext->pNext));
    141         pReqs = NULL;
    142         while (pReq)
    143         {
    144             Assert(pReq->enmState == RTREQSTATE_QUEUED);
    145             Assert(pReq->uOwner.hQueue == pQueue);
    146             PRTREQ pCur = pReq;
    147             pReq = pReq->pNext;
    148             pCur->pNext = pReqs;
    149             pReqs = pCur;
    150         }
    151 
     152        else
     153            ASMAtomicWriteBool(&pQueue->fBusy, true);
    152154
    153155        /*
     
    157159        {
    158160            /* Unchain the first request and advance the list. */
    159             pReq = pReqs;
     161            PRTREQ pReq = pReqs;
    160162            pReqs = pReqs->pNext;
    161163            pReq->pNext = NULL;
    162164
    163             /* Process the request */
     165            /* Process the request. */
    164166            rc = rtReqProcessOne(pReq);
    165167            AssertRC(rc);
    166168            if (rc != VINF_SUCCESS)
    167                 break; /** @todo r=bird: we're dropping requests here! Add 2nd queue that can hold them. (will fix when writing a testcase)  */
     169            {
     170                /* Propagate the return code to caller.  If more requests pending, queue them for later. */
     171                if (pReqs)
     172                {
     173                    pReqs = ASMAtomicXchgPtrT(&pQueue->pAlreadyPendingReqs, pReqs, PRTREQ);
     174                    Assert(!pReqs);
     175                }
     176                break;
     177            }
    168178        }
     179        if (rc != VINF_SUCCESS)
     180            break;
    169181    }
    170182
  • trunk/src/VBox/Runtime/include/internal/req.h

    r56290 r60121  
    130130    /** Set if busy (pending or processing requests). */
    131131    bool volatile           fBusy;
    132     /** Head of the request queue. Atomic. */
     132    /** Head of the request queue (LIFO). Atomic. */
    133133    volatile PRTREQ         pReqs;
     134    /** List of requests pending after a non-VINF_SUCCESS status code forced
     135     * RTReqQueueProcess to stop processing requestins.  This is in FIFO order. */
     136    volatile PRTREQ         pAlreadyPendingReqs;
    134137    /** The last index used during alloc/free. */
    135138    volatile uint32_t       iReqFree;
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