VirtualBox

Ignore:
Timestamp:
May 1, 2021 6:15:13 PM (4 years ago)
Author:
vboxsync
svn:sync-xref-src-repo-rev:
144147
Message:

IPRT/RTReq: Added a RTReqCancel function. Changed the behavior of the RTREQFLAGS_NO_WAIT to optionally return the request handle rather than obstinately returning NIL even when the phReq parameter is not NULL. This makes the usage clearer and allows canceling NO_WAIT requests. (Needed in DrvAudio.) bugref:9890

Location:
trunk/src/VBox/Runtime/common/misc
Files:
3 edited

Legend:

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

    r85121 r88813  
    197197         * Check packet state.
    198198         */
    199         switch (pReq->enmState)
     199        RTREQSTATE const enmState = pReq->enmState;
     200        switch (enmState)
    200201        {
    201202            case RTREQSTATE_ALLOCATED:
     
    203204                break;
    204205            default:
    205                 AssertMsgFailed(("Invalid state %d!\n", pReq->enmState));
    206                 return 0;
     206                AssertMsgFailedReturn(("Invalid state %d!\n", enmState), 0);
    207207        }
    208208
     
    248248
    249249    /*
    250      * Insert it.  Donate the caller's reference if RTREQFLAGS_NO_WAIT is set,
    251      * otherwise retain another reference for the queue.
     250     * Insert it.  Always grab a reference for the queue (we used to
     251     * donate the caller's reference in the NO_WAIT case once upon a time).
    252252     */
    253253    pReq->uSubmitNanoTs = RTTimeNanoTS();
    254254    pReq->enmState      = RTREQSTATE_QUEUED;
    255255    unsigned fFlags = ((RTREQ volatile *)pReq)->fFlags;                    /* volatile paranoia */
    256     if (!(fFlags & RTREQFLAGS_NO_WAIT))
    257         RTReqRetain(pReq);
     256    RTReqRetain(pReq);
    258257
    259258    if (!pReq->fPoolOrQueue)
     
    285284    AssertPtrReturn(pReq, VERR_INVALID_HANDLE);
    286285    AssertReturn(pReq->u32Magic == RTREQ_MAGIC, VERR_INVALID_HANDLE);
    287     AssertMsgReturn(   pReq->enmState == RTREQSTATE_QUEUED
    288                     || pReq->enmState == RTREQSTATE_PROCESSING
    289                     || pReq->enmState == RTREQSTATE_COMPLETED,
    290                     ("Invalid state %d\n", pReq->enmState),
     286    RTREQSTATE enmState = pReq->enmState;
     287    AssertMsgReturn(   enmState == RTREQSTATE_QUEUED
     288                    || enmState == RTREQSTATE_PROCESSING
     289                    || enmState == RTREQSTATE_COMPLETED
     290                    || enmState == RTREQSTATE_CANCELLED,
     291                    ("Invalid state %d\n", enmState),
    291292                    VERR_RT_REQUEST_STATE);
    292293    AssertMsgReturn(pReq->uOwner.hQueue && pReq->EventSem != NIL_RTSEMEVENT,
     
    313314    }
    314315    if (rc == VINF_SUCCESS)
    315         ASMAtomicXchgSize(&pReq->fEventSemClear, true);
     316        ASMAtomicWriteBool(&pReq->fEventSemClear, true);
    316317    if (pReq->enmState == RTREQSTATE_COMPLETED)
    317318        rc = VINF_SUCCESS;
     
    324325
    325326
     327RTDECL(int) RTReqCancel(PRTREQ hReq)
     328{
     329    LogFlow(("RTReqCancel: hReq=%p\n", hReq));
     330
     331    /*
     332     * Verify the supplied package.
     333     */
     334    PRTREQINT pReq = hReq;
     335    AssertPtrReturn(pReq, VERR_INVALID_HANDLE);
     336    AssertReturn(pReq->u32Magic == RTREQ_MAGIC, VERR_INVALID_HANDLE);
     337    //AssertMsgReturn(pReq->enmState == RTREQSTATE_ALLOCATED, ("%d\n", pReq->enmState), VERR_RT_REQUEST_STATE);
     338    AssertMsgReturn(pReq->uOwner.hQueue && !pReq->pNext && pReq->EventSem != NIL_RTSEMEVENT,
     339                    ("Invalid request package! Anyone cooking their own packages???\n"),
     340                    VERR_RT_REQUEST_INVALID_PACKAGE);
     341    AssertMsgReturn(pReq->enmType > RTREQTYPE_INVALID && pReq->enmType < RTREQTYPE_MAX,
     342                    ("Invalid package type %d valid range %d-%d inclusively. This was verified on alloc too...\n",
     343                     pReq->enmType, RTREQTYPE_INVALID + 1, RTREQTYPE_MAX - 1),
     344                    VERR_RT_REQUEST_INVALID_TYPE);
     345
     346    /*
     347     * Try cancel the request itself by changing its state.
     348     */
     349    int rc;
     350    if (ASMAtomicCmpXchgU32((uint32_t volatile *)&pReq->enmState, RTREQSTATE_CANCELLED, RTREQSTATE_QUEUED))
     351    {
     352        if (pReq->fPoolOrQueue)
     353            rtReqPoolCancel(pReq->uOwner.hPool, pReq);
     354        rc = VINF_SUCCESS;
     355    }
     356    else
     357    {
     358        Assert(pReq->enmState == RTREQSTATE_PROCESSING || pReq->enmState == RTREQSTATE_COMPLETED);
     359        rc = VERR_RT_REQUEST_STATE;
     360    }
     361
     362    LogFlow(("RTReqCancel: returns %Rrc\n", rc));
     363    return rc;
     364}
     365RT_EXPORT_SYMBOL(RTReqCancel);
     366
     367
    326368RTDECL(int) RTReqGetStatus(PRTREQ hReq)
    327369{
     
    347389
    348390    /*
    349      * Process the request.
    350      */
    351     Assert(pReq->enmState == RTREQSTATE_QUEUED);
    352     pReq->enmState = RTREQSTATE_PROCESSING;
     391     * Try switch the request status to processing.
     392     */
    353393    int     rcRet = VINF_SUCCESS;           /* the return code of this function. */
    354394    int     rcReq = VERR_NOT_IMPLEMENTED;   /* the request status. */
    355     switch (pReq->enmType)
     395    if (ASMAtomicCmpXchgU32((uint32_t volatile *)&pReq->enmState, RTREQSTATE_PROCESSING, RTREQSTATE_QUEUED))
    356396    {
    357397        /*
    358          * A packed down call frame.
     398         * Process the request.
    359399         */
    360         case RTREQTYPE_INTERNAL:
     400        pReq->enmState = RTREQSTATE_PROCESSING;
     401        switch (pReq->enmType)
    361402        {
    362             uintptr_t *pauArgs = &pReq->u.Internal.aArgs[0];
    363             union
     403            /*
     404             * A packed down call frame.
     405             */
     406            case RTREQTYPE_INTERNAL:
    364407            {
    365                 PFNRT pfn;
    366                 DECLCALLBACKMEMBER(int, pfn00,(void));
    367                 DECLCALLBACKMEMBER(int, pfn01,(uintptr_t));
    368                 DECLCALLBACKMEMBER(int, pfn02,(uintptr_t, uintptr_t));
    369                 DECLCALLBACKMEMBER(int, pfn03,(uintptr_t, uintptr_t, uintptr_t));
    370                 DECLCALLBACKMEMBER(int, pfn04,(uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    371                 DECLCALLBACKMEMBER(int, pfn05,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    372                 DECLCALLBACKMEMBER(int, pfn06,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    373                 DECLCALLBACKMEMBER(int, pfn07,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    374                 DECLCALLBACKMEMBER(int, pfn08,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    375                 DECLCALLBACKMEMBER(int, pfn09,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    376                 DECLCALLBACKMEMBER(int, pfn10,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    377                 DECLCALLBACKMEMBER(int, pfn11,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    378                 DECLCALLBACKMEMBER(int, pfn12,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
    379             } u;
    380             u.pfn = pReq->u.Internal.pfn;
     408                uintptr_t *pauArgs = &pReq->u.Internal.aArgs[0];
     409                union
     410                {
     411                    PFNRT pfn;
     412                    DECLCALLBACKMEMBER(int, pfn00,(void));
     413                    DECLCALLBACKMEMBER(int, pfn01,(uintptr_t));
     414                    DECLCALLBACKMEMBER(int, pfn02,(uintptr_t, uintptr_t));
     415                    DECLCALLBACKMEMBER(int, pfn03,(uintptr_t, uintptr_t, uintptr_t));
     416                    DECLCALLBACKMEMBER(int, pfn04,(uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     417                    DECLCALLBACKMEMBER(int, pfn05,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     418                    DECLCALLBACKMEMBER(int, pfn06,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     419                    DECLCALLBACKMEMBER(int, pfn07,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     420                    DECLCALLBACKMEMBER(int, pfn08,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     421                    DECLCALLBACKMEMBER(int, pfn09,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     422                    DECLCALLBACKMEMBER(int, pfn10,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     423                    DECLCALLBACKMEMBER(int, pfn11,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     424                    DECLCALLBACKMEMBER(int, pfn12,(uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t, uintptr_t));
     425                } u;
     426                u.pfn = pReq->u.Internal.pfn;
    381427#ifndef RT_ARCH_X86
    382             switch (pReq->u.Internal.cArgs)
    383             {
    384                 case 0:  rcRet = u.pfn00(); break;
    385                 case 1:  rcRet = u.pfn01(pauArgs[0]); break;
    386                 case 2:  rcRet = u.pfn02(pauArgs[0], pauArgs[1]); break;
    387                 case 3:  rcRet = u.pfn03(pauArgs[0], pauArgs[1], pauArgs[2]); break;
    388                 case 4:  rcRet = u.pfn04(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3]); break;
    389                 case 5:  rcRet = u.pfn05(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4]); break;
    390                 case 6:  rcRet = u.pfn06(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5]); break;
    391                 case 7:  rcRet = u.pfn07(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6]); break;
    392                 case 8:  rcRet = u.pfn08(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7]); break;
    393                 case 9:  rcRet = u.pfn09(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8]); break;
    394                 case 10: rcRet = u.pfn10(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9]); break;
    395                 case 11: rcRet = u.pfn11(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9], pauArgs[10]); break;
    396                 case 12: rcRet = u.pfn12(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9], pauArgs[10], pauArgs[11]); break;
    397                 default:
    398                     AssertReleaseMsgFailed(("cArgs=%d\n", pReq->u.Internal.cArgs));
    399                     rcRet = rcReq = VERR_INTERNAL_ERROR;
    400                     break;
    401             }
     428                switch (pReq->u.Internal.cArgs)
     429                {
     430                    case 0:  rcRet = u.pfn00(); break;
     431                    case 1:  rcRet = u.pfn01(pauArgs[0]); break;
     432                    case 2:  rcRet = u.pfn02(pauArgs[0], pauArgs[1]); break;
     433                    case 3:  rcRet = u.pfn03(pauArgs[0], pauArgs[1], pauArgs[2]); break;
     434                    case 4:  rcRet = u.pfn04(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3]); break;
     435                    case 5:  rcRet = u.pfn05(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4]); break;
     436                    case 6:  rcRet = u.pfn06(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5]); break;
     437                    case 7:  rcRet = u.pfn07(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6]); break;
     438                    case 8:  rcRet = u.pfn08(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7]); break;
     439                    case 9:  rcRet = u.pfn09(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8]); break;
     440                    case 10: rcRet = u.pfn10(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9]); break;
     441                    case 11: rcRet = u.pfn11(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9], pauArgs[10]); break;
     442                    case 12: rcRet = u.pfn12(pauArgs[0], pauArgs[1], pauArgs[2], pauArgs[3], pauArgs[4], pauArgs[5], pauArgs[6], pauArgs[7], pauArgs[8], pauArgs[9], pauArgs[10], pauArgs[11]); break;
     443                    default:
     444                        AssertReleaseMsgFailed(("cArgs=%d\n", pReq->u.Internal.cArgs));
     445                        rcRet = rcReq = VERR_INTERNAL_ERROR;
     446                        break;
     447                }
    402448#else /* RT_ARCH_X86 */
    403             size_t cbArgs = pReq->u.Internal.cArgs * sizeof(uintptr_t);
     449                size_t cbArgs = pReq->u.Internal.cArgs * sizeof(uintptr_t);
    404450# ifdef __GNUC__
    405             __asm__ __volatile__("movl  %%esp, %%edx\n\t"
    406                                  "subl  %2, %%esp\n\t"
    407                                  "andl  $0xfffffff0, %%esp\n\t"
    408                                  "shrl  $2, %2\n\t"
    409                                  "movl  %%esp, %%edi\n\t"
    410                                  "rep movsl\n\t"
    411                                  "movl  %%edx, %%edi\n\t"
    412                                  "call  *%%eax\n\t"
    413                                  "mov   %%edi, %%esp\n\t"
    414                                  : "=a" (rcRet),
    415                                    "=S" (pauArgs),
    416                                    "=c" (cbArgs)
    417                                  : "0" (u.pfn),
    418                                    "1" (pauArgs),
    419                                    "2" (cbArgs)
    420                                  : "edi", "edx");
     451                __asm__ __volatile__("movl  %%esp, %%edx\n\t"
     452                                     "subl  %2, %%esp\n\t"
     453                                     "andl  $0xfffffff0, %%esp\n\t"
     454                                     "shrl  $2, %2\n\t"
     455                                     "movl  %%esp, %%edi\n\t"
     456                                     "rep movsl\n\t"
     457                                     "movl  %%edx, %%edi\n\t"
     458                                     "call  *%%eax\n\t"
     459                                     "mov   %%edi, %%esp\n\t"
     460                                     : "=a" (rcRet),
     461                                       "=S" (pauArgs),
     462                                       "=c" (cbArgs)
     463                                     : "0" (u.pfn),
     464                                       "1" (pauArgs),
     465                                       "2" (cbArgs)
     466                                     : "edi", "edx");
    421467# else
    422             __asm
    423             {
    424                 xor     edx, edx        /* just mess it up. */
    425                 mov     eax, u.pfn
    426                 mov     ecx, cbArgs
    427                 shr     ecx, 2
    428                 mov     esi, pauArgs
    429                 mov     ebx, esp
    430                 sub     esp, cbArgs
    431                 and     esp, 0xfffffff0
    432                 mov     edi, esp
    433                 rep movsd
    434                 call    eax
    435                 mov     esp, ebx
    436                 mov     rcRet, eax
    437             }
     468                __asm
     469                {
     470                    xor     edx, edx        /* just mess it up. */
     471                    mov     eax, u.pfn
     472                    mov     ecx, cbArgs
     473                    shr     ecx, 2
     474                    mov     esi, pauArgs
     475                    mov     ebx, esp
     476                    sub     esp, cbArgs
     477                    and     esp, 0xfffffff0
     478                    mov     edi, esp
     479                    rep movsd
     480                    call    eax
     481                    mov     esp, ebx
     482                    mov     rcRet, eax
     483                }
    438484# endif
    439485#endif /* RT_ARCH_X86 */
    440             if ((pReq->fFlags & (RTREQFLAGS_RETURN_MASK)) == RTREQFLAGS_VOID)
    441                 rcRet = VINF_SUCCESS;
    442             rcReq = rcRet;
    443             break;
     486                if ((pReq->fFlags & (RTREQFLAGS_RETURN_MASK)) == RTREQFLAGS_VOID)
     487                    rcRet = VINF_SUCCESS;
     488                rcReq = rcRet;
     489                break;
     490            }
     491
     492            default:
     493                AssertMsgFailed(("pReq->enmType=%d\n", pReq->enmType));
     494                rcReq = VERR_NOT_IMPLEMENTED;
     495                break;
    444496        }
    445 
    446         default:
    447             AssertMsgFailed(("pReq->enmType=%d\n", pReq->enmType));
    448             rcReq = VERR_NOT_IMPLEMENTED;
    449             break;
     497    }
     498    else
     499    {
     500        Assert(pReq->enmState == RTREQSTATE_CANCELLED);
     501        rcReq = VERR_CANCELLED;
    450502    }
    451503
     
    463515        LogFlow(("rtReqProcessOne: Completed request %p: rcReq=%Rrc rcRet=%Rrc - notifying waiting thread\n",
    464516                 pReq, rcReq, rcRet));
    465         ASMAtomicXchgSize(&pReq->fEventSemClear, false);
     517        ASMAtomicWriteBool(&pReq->fEventSemClear, false);
    466518        int rc2 = RTSemEventSignal(pReq->EventSem);
    467519        if (rc2 != VINF_SUCCESS)
  • trunk/src/VBox/Runtime/common/misc/reqpool.cpp

    r88810 r88813  
    187187    /** The number of requests submitted. */
    188188    uint64_t                cReqSubmitted;
     189    /** The number of cancelled. */
     190    uint64_t                cReqCancelled;
    189191
    190192    /** Head of the request recycling LIFO. */
     
    231233
    232234    uint32_t cMsCurPushBack;
    233     if ((cMsRange >> 2) >= cSteps)
     235    if (cSteps == 0 /* disabled */)
     236        cMsCurPushBack = 0;
     237    else if ((cMsRange >> 2) >= cSteps)
    234238        cMsCurPushBack = cMsRange / cSteps * iStep;
    235239    else
     
    558562    pReq->pNext = NULL;
    559563    *pPool->ppPendingRequests = pReq;
    560     pPool->ppPendingRequests  = (PRTREQINT*)&pReq->pNext;
     564    pPool->ppPendingRequests  = (PRTREQINT *)&pReq->pNext;
    561565    pPool->cCurPendingRequests++;
    562566
     
    588592     */
    589593    rtReqPoolCreateNewWorker(pPool);
     594
     595    RTCritSectLeave(&pPool->CritSect);
     596    return;
     597}
     598
     599
     600/**
     601 * Worker for RTReqCancel that looks for the request in the pending list and
     602 * completes it if found there.
     603 *
     604 * @param   pPool               The request thread pool.
     605 * @param   pReq                The request.
     606 */
     607DECLHIDDEN(void) rtReqPoolCancel(PRTREQPOOLINT pPool, PRTREQINT pReq)
     608{
     609    RTCritSectEnter(&pPool->CritSect);
     610
     611    pPool->cReqCancelled++;
     612
     613    /*
     614     * Check if the request is in the pending list.
     615     */
     616    PRTREQINT pPrev = NULL;
     617    PRTREQINT pCur  = pPool->pPendingRequests;
     618    while (pCur)
     619        if (pCur != pReq)
     620        {
     621            pPrev = pCur;
     622            pCur  = pCur->pNext;
     623        }
     624        else
     625        {
     626            /*
     627             * Unlink it and process it.
     628             */
     629            if (!pPrev)
     630            {
     631                pPool->pPendingRequests = pReq->pNext;
     632                if (!pReq->pNext)
     633                    pPool->ppPendingRequests = &pPool->pPendingRequests;
     634            }
     635            else
     636            {
     637                pPrev->pNext = pReq->pNext;
     638                if (!pReq->pNext)
     639                    pPool->ppPendingRequests = (PRTREQINT *)&pPrev->pNext;
     640            }
     641            Assert(pPool->cCurPendingRequests > 0);
     642            pPool->cCurPendingRequests--;
     643
     644            rtReqProcessOne(pReq);
     645            break;
     646        }
    590647
    591648    RTCritSectLeave(&pPool->CritSect);
     
    692749    pPool->cCurActiveRequests   = 0;
    693750    pPool->cReqSubmitted        = 0;
     751    pPool->cReqCancelled        = 0;
    694752    pPool->pFreeRequests        = NULL;
    695753    pPool->cCurFreeRequests     = 0;
     
    9561014        case RTREQPOOLSTAT_REQUESTS_PROCESSED:          u64 = pPool->cReqProcessed; break;
    9571015        case RTREQPOOLSTAT_REQUESTS_SUBMITTED:          u64 = pPool->cReqSubmitted; break;
     1016        case RTREQPOOLSTAT_REQUESTS_CANCELLED:          u64 = pPool->cReqCancelled; break;
    9581017        case RTREQPOOLSTAT_REQUESTS_PENDING:            u64 = pPool->cCurPendingRequests; break;
    9591018        case RTREQPOOLSTAT_REQUESTS_ACTIVE:             u64 = pPool->cCurActiveRequests; break;
     
    11261185    AssertPtrReturn(pfnFunction, VERR_INVALID_POINTER);
    11271186    AssertMsgReturn(!((uint32_t)fFlags & ~(uint32_t)(RTREQFLAGS_NO_WAIT | RTREQFLAGS_RETURN_MASK)), ("%#x\n", (uint32_t)fFlags), VERR_INVALID_PARAMETER);
    1128     if (!(fFlags & RTREQFLAGS_NO_WAIT))
     1187    if (!(fFlags & RTREQFLAGS_NO_WAIT) || phReq)
    11291188    {
    11301189        AssertPtrReturn(phReq, VERR_INVALID_POINTER);
     
    11591218    }
    11601219
    1161     if (!(fFlags & RTREQFLAGS_NO_WAIT))
     1220    if (phReq)
    11621221    {
    11631222        *phReq = pReq;
     
    11651224    }
    11661225    else
     1226    {
     1227        RTReqRelease(pReq);
    11671228        LogFlow(("RTReqPoolCallExV: returns %Rrc\n", rc));
     1229    }
    11681230    return rc;
    11691231}
  • trunk/src/VBox/Runtime/common/misc/reqqueue.cpp

    r82968 r88813  
    237237    {
    238238        AssertPtrReturn(ppReq, VERR_INVALID_POINTER);
    239         *ppReq = NULL;
     239        *ppReq = NIL_RTREQ;
    240240    }
    241241
     
    269269        pReq = NULL;
    270270    }
    271     if (!(fFlags & RTREQFLAGS_NO_WAIT))
     271    if (ppReq)
    272272    {
    273273        *ppReq = pReq;
     
    275275    }
    276276    else
     277    {
     278        RTReqRelease(pReq);
    277279        LogFlow(("RTReqQueueCallV: returns %Rrc\n", rc));
     280    }
    278281    Assert(rc != VERR_INTERRUPTED);
    279282    return rc;
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