⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 util.h

📁 ril source code for Windows CE
💻 H
📖 第 1 页 / 共 3 页
字号:

        // Got an item in the queue
        rpItem = m_rgpItems[0];
        m_nUsed--;
        if ( (sizeof(m_rgpItems)/sizeof(m_rgpItems[0])) < m_nUsed )
        {
            hr = E_ABORT;
            goto Error;
        }
        memmove(m_rgpItems, (BYTE*)m_rgpItems + sizeof(Type*), sizeof(Type*) * m_nUsed);
        m_rgpItems[m_nUsed] = NULL;

        // Signal the Get event
        (void)SetEvent(m_hGetEvent);
    }

Error:
    return hr;
}


//
// Retrieve a pointer to the first element in the queue
//
template <class Type, UINT Size>
BOOL CQueue<Type, Size>::Peek(Type*& rpItem)
{
    SYNCBLOCK(m_cs);
    return PeekInternal(rpItem);
}


//
// Retrieve a pointer to the first element in the queue (internal version)
//
template <class Type, UINT Size>
BOOL CQueue<Type, Size>::PeekInternal(Type*& rpItem)
{
    DEBUGCHK(FALSE != m_fInited);

    BOOL fRet = FALSE;

    rpItem = NULL;

    if (!m_nUsed) {
        goto Error;
    }

    rpItem = m_rgpItems[0];
    DEBUGCHK(NULL != rpItem);
    fRet = TRUE;

Error:
    return fRet;
}


//
// Dequeue an element from the queue, if it satisfies a condition
//    (will wait for the next element for a specified timeout)
//
template <class Type, UINT Size>
HRESULT CQueue<Type, Size>::ConditionalGet(const PFN_QUEUE_TEST pfnTest, const DWORD dwData, Type*& rpItem,
                                           const DWORD dwTimeout)
{
    SYNCBLOCK(m_cs);

    HRESULT hr = S_OK;

    // Wait for an element to appear in the queue
    hr = WaitForNextItemInternal(dwTimeout);
    if (FAILED(hr)) {
        goto Error;
    }

    // Peek the first element
    if (!PeekInternal(rpItem)) {
        DEBUGCHK(FALSE);
    }

    // See if the first element satisfies the condition
    if (!pfnTest(rpItem, dwData)) {
        rpItem = NULL;
        hr = E_FAIL;
        goto Error;
    }

    // Retrieve the first element
    if (FAILED(GetInternal(rpItem, INFINITE))) {
        DEBUGCHK(FALSE);
    }
    DEBUGCHK(NULL != rpItem);

Error:
    return hr;
}


//
// Wait until an element appears in the queue
//
template <class Type, UINT Size>
HRESULT CQueue<Type, Size>::WaitForNextItem(const DWORD dwTimeout)
{
    SYNCBLOCK(m_cs);
    return WaitForNextItemInternal(dwTimeout);
}


//
// Wait until an item appears in the queue (internal version)
//
template <class Type, UINT Size>
HRESULT CQueue<Type, Size>::WaitForNextItemInternal(const DWORD dwTimeout)
{
    FUNCTION_TRACE(CQueue::WaitForNextItemInternal);
    DEBUGCHK(FALSE != m_fInited);

    HANDLE rghEvents[2] = { m_hPutEvent, m_hCancelEvent };
    DWORD dwWait;
    HRESULT hr = S_OK;

    if (m_fInited) {
        while(1) {
            // Are there any items in the queue?
            if (m_nUsed) {
                // Yes -- proceed
                break;
            } else {
                // No - need to wait for Put to happen
                UNSYNCBLOCK(m_cs);

                dwWait = WaitForMultipleObjects(2, rghEvents, FALSE, dwTimeout);
                if (WAIT_OBJECT_0 + 1 == dwWait) {
                    // We hit the terminate event -- quit
                    hr = RIL_E_CANCELLED;
                    goto Error;
                } else if (WAIT_TIMEOUT == dwWait) {
                    // We timed out-- quit
                    hr = RIL_E_TIMEDOUT;
                    goto Error;
                } else {
                    DEBUGCHK(WAIT_OBJECT_0 == dwWait);
                }
            }
        }

        DEBUGCHK(m_nUsed != 0);
    }

Error:
    return hr;
}


//
// Wait until an empty slot appears in the queue (internal version)
//
template <class Type, UINT Size>
BOOL CQueue<Type, Size>::WaitForEmptySpaceInternal(const DWORD dwTimeout)
{
    DEBUGCHK(FALSE != m_fInited);

    HANDLE rghEvents[2] = { m_hGetEvent, m_hCancelEvent };
    DWORD dwWait;
    BOOL fRet = FALSE;

    if (m_fInited) {
        while (1) {
            // Is there space in the queue?
            if (m_nUsed < Size) {
                // Yes -- proceed
                break;
            } else {
                DEBUGCHK(Size == m_nUsed);

                // No -- need to wait for Get to happen
                UNSYNCBLOCK(m_cs);

                dwWait = WaitForMultipleObjects(2, rghEvents, FALSE, dwTimeout);
                if (WAIT_OBJECT_0 != dwWait) {
                    // We hit the terminate event or timed out
                    goto Error;
                }
            }
        }
    }

    DEBUGCHK(m_nUsed < Size);
    fRet = TRUE;

Error:
    return fRet;
}


//
// Enum all queue elements, calling the provided routine for each item
//
template <class Type, UINT Size>
void CQueue<Type, Size>::Enum(const PFN_QUEUE_ENUM pfnEnum, const DWORD dwData, const BOOL fClear)
{
    SYNCBLOCK(m_cs);

    DEBUGCHK(FALSE != m_fInited);

    if (m_fInited) {
        for (UINT i = 0; i < m_nUsed; i++) {
            if (pfnEnum((void*)m_rgpItems[i], dwData)) {
                break;
            }
        }

        if (fClear) {
            // We also need to clear the queue
            for (i = 0; i < m_nUsed; i++) {
                delete m_rgpItems[i];
                m_rgpItems[i] = NULL;
            }
            m_nUsed = 0;
        }
    }
}


//
// Determine if the queue is empty
//
template <class Type, UINT Size>
BOOL CQueue<Type, Size>::FEmpty()
{
    SYNCBLOCK(m_cs);
    return !m_nUsed;
}


//
// Priority queue ctor
//
template <class Type, UINT Size>
CPriorityQueue<Type, Size>::CPriorityQueue()
: CQueue<Type, Size>(FALSE)
{
}


//
// Priority queue dtor
//
template <class Type, UINT Size>
CPriorityQueue<Type, Size>::~CPriorityQueue()
{
}


//
// Enqueue an element
//
template <class Type, UINT Size>
BOOL CPriorityQueue<Type, Size>::Put(Type* const pNew, const DWORD dwTimeout)
{
    SYNCBLOCK(m_cs);

    DEBUGCHK(FALSE != m_fInited);
    DEBUGCHK(pNew != NULL);

    UINT i;
    BOOL fRet = FALSE;

    if (m_fInited) {
        if (!WaitForEmptySpaceInternal(dwTimeout)) {
            goto Error;
        }

        if ( m_nUsed >= Size )
            {
            ASSERT( FALSE );
            goto Error;
            }

        // We have space in the queue -- find the correct spot for this item
        for (i = 0; i < m_nUsed; i++) {
            if (pNew->GetPriority() < m_rgpItems[i]->GetPriority()) {
                // We found the first item whose pri is lower (i.e., greater) than the one for the new item --
                //     shift other items in the queue
                memmove(&m_rgpItems[i + 1], &m_rgpItems[i], sizeof(Type*) * (m_nUsed - i));
                break;
            }
        }

        // Insert the new item
        m_rgpItems[i] = pNew;
        m_nUsed++;

        // Signal the Put event
        (void)SetEvent(m_hPutEvent);
    }

    fRet = TRUE;

Error:
    return fRet;
}


//
// List ctor
//
template <class Type>
CDblList<Type>::CDblList()
: m_pElems(NULL)
{
    InitializeCriticalSection(&m_cs);
}


//
// List dtor
//
template <class Type>
CDblList<Type>::~CDblList()
{
    DeleteCriticalSection(&m_cs);
}


//
// Add an item to the list
//
template <class Type>
BOOL CDblList<Type>::Add(Type* const pAdd)
{
    SYNCBLOCK(m_cs);

    BOOL fRet = FALSE;

    // Check thaat the new element exists
    if (!pAdd) {
        goto Error;
    }

    // Add the new element at the front
    pAdd->SetNext(m_pElems);
    pAdd->SetPrev(NULL);

    if (pAdd->GetNext()) {
        pAdd->GetNext()->SetPrev(pAdd);
    }

    m_pElems = pAdd;
    fRet = TRUE;

Error:
    return fRet;
}


//
// Remove an item from the list
//
template <class Type>
BOOL CDblList<Type>::Remove(const Type* const pRemove)
{
    SYNCBLOCK(m_cs);

    BOOL fRet = FALSE;

    // Check that the element to be removed exists
    if (!pRemove) {
        goto Error;
    }

    // Is this element head of the list?
    if (pRemove == m_pElems) {
        // Yes
        m_pElems = (Type*)pRemove->GetNext();
    } else {
        // No
        pRemove->GetPrev()->SetNext(pRemove->GetNext());
    }

    // Re-route the links
    if (pRemove->GetNext()) {
        pRemove->GetNext()->SetPrev(pRemove->GetPrev());
    }

    fRet = TRUE;

Error:
    return fRet;
}


//
// Enum all list elements, calling the provided routine for each item
//
template <class Type>
void CDblList<Type>::Enum(const PFN_LIST_ENUM pfnEnum, const DWORD dwData)
{
    SYNCBLOCK(m_cs);

    Type* pNext;
    for (Type* pWalk = m_pElems; pWalk; pWalk = pNext) {
        pNext = (Type*)pWalk->GetNext();
        if (pfnEnum((void*)pWalk, dwData)) {
            break;
        }
    }
}


⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -