📄 util.h
字号:
// 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 + -