示例#1
0
RTDECL(int) RTReqQueueDestroy(RTREQQUEUE hQueue)
{
    /*
     * Check input.
     */
    if (hQueue == NIL_RTREQQUEUE)
        return VINF_SUCCESS;
    PRTREQQUEUEINT pQueue = hQueue;
    AssertPtrReturn(pQueue, VERR_INVALID_HANDLE);
    AssertReturn(ASMAtomicCmpXchgU32(&pQueue->u32Magic, RTREQQUEUE_MAGIC_DEAD, RTREQQUEUE_MAGIC), VERR_INVALID_HANDLE);

    RTSemEventDestroy(pQueue->EventSem);
    pQueue->EventSem = NIL_RTSEMEVENT;

    for (unsigned i = 0; i < RT_ELEMENTS(pQueue->apReqFree); i++)
    {
        PRTREQ pReq = (PRTREQ)ASMAtomicXchgPtr((void **)&pQueue->apReqFree[i], NULL);
        while (pReq)
        {
            PRTREQ pNext = pReq->pNext;
            rtReqFreeIt(pReq);
            pReq = pNext;
        }
    }

    RTMemFree(pQueue);
    return VINF_SUCCESS;
}
示例#2
0
RTDECL(uint32_t) RTReqRelease(PRTREQ hReq)
{
    /*
     * Ignore NULL and validate the request.
     */
    if (!hReq)
        return 0;
    PRTREQINT pReq = hReq;
    AssertPtrReturn(pReq, UINT32_MAX);
    AssertReturn(pReq->u32Magic == RTREQ_MAGIC, UINT32_MAX);

    /*
     * Drop a reference, recycle the request when we reach 0.
     */
    uint32_t cRefs = ASMAtomicDecU32(&pReq->cRefs);
    if (cRefs == 0)
    {
        /*
         * Check packet state.
         */
        switch (pReq->enmState)
        {
            case RTREQSTATE_ALLOCATED:
            case RTREQSTATE_COMPLETED:
                break;
            default:
                AssertMsgFailed(("Invalid state %d!\n", pReq->enmState));
                return 0;
        }

        /*
         * Make it a free packet and put it into one of the free packet lists.
         */
        pReq->enmState = RTREQSTATE_FREE;
        pReq->iStatusX = VERR_RT_REQUEST_STATUS_FREED;
        pReq->enmType  = RTREQTYPE_INVALID;

        bool fRecycled;
        if (pReq->fPoolOrQueue)
            fRecycled = rtReqPoolRecycle(pReq->uOwner.hPool, pReq);
        else
            fRecycled = rtReqQueueRecycle(pReq->uOwner.hQueue, pReq);
        if (!fRecycled)
            rtReqFreeIt(pReq);
    }

    return cRefs;
}
示例#3
0
/**
 * Re-initializes a request when it's being recycled.
 *
 * @returns IRPT status code, the request is freed on failure.
 * @param   pReq                The request.
 * @param   enmType             The request type.
 */
DECLHIDDEN(int) rtReqReInit(PRTREQINT pReq, RTREQTYPE enmType)
{
    Assert(pReq->u32Magic == RTREQ_MAGIC);
    Assert(pReq->enmType  == RTREQTYPE_INVALID);
    Assert(pReq->enmState == RTREQSTATE_FREE);
    Assert(pReq->cRefs    == 0);

    /*
     * Make sure the event sem is not signaled.
     */
    if (!pReq->fEventSemClear)
    {
        int rc = RTSemEventWait(pReq->EventSem, 0);
        if (rc != VINF_SUCCESS && rc != VERR_TIMEOUT)
        {
            /*
             * This shall not happen, but if it does we'll just destroy
             * the semaphore and create a new one.
             */
            AssertMsgFailed(("rc=%Rrc from RTSemEventWait(%#x).\n", rc, pReq->EventSem));
            RTSemEventDestroy(pReq->EventSem);
            rc = RTSemEventCreate(&pReq->EventSem);
            if (RT_FAILURE(rc))
            {
                AssertRC(rc);
                pReq->EventSem = NIL_RTSEMEVENT;
                rtReqFreeIt(pReq);
                return rc;
            }
        }
        pReq->fEventSemClear = true;
    }
    else
        Assert(RTSemEventWait(pReq->EventSem, 0) == VERR_TIMEOUT);

    /*
     * Initialize the packet and return it.
     */
    ASMAtomicWriteNullPtr(&pReq->pNext);
    pReq->iStatusX = VERR_RT_REQUEST_STATUS_STILL_PENDING;
    pReq->enmState = RTREQSTATE_ALLOCATED;
    pReq->fFlags   = RTREQFLAGS_IPRT_STATUS;
    pReq->enmType  = enmType;
    pReq->cRefs    = 1;
    return VINF_SUCCESS;
}