diff options
Diffstat (limited to 'source/api_wrappers/linux/CSemaphoreQueue.cpp')
-rw-r--r-- | source/api_wrappers/linux/CSemaphoreQueue.cpp | 121 |
1 files changed, 121 insertions, 0 deletions
diff --git a/source/api_wrappers/linux/CSemaphoreQueue.cpp b/source/api_wrappers/linux/CSemaphoreQueue.cpp new file mode 100644 index 0000000..0a2f573 --- /dev/null +++ b/source/api_wrappers/linux/CSemaphoreQueue.cpp @@ -0,0 +1,121 @@ +/******************************************************************************* + * Copyright (C) ST-Ericsson SA 2011 + * License terms: 3-clause BSD license + ******************************************************************************/ + +#include <pthread.h> +#include <assert.h> +#include "Types.h" +#include "CEventObject.h" +#include "CSemaphore.h" +#include "CSemaphoreQueue.h" + +CSemaphoreQueue::CSemaphoreQueue(unsigned int MaxCount) : m_MaximumCount(MaxCount) +{ + m_pEventObject = new CEventObject(); + m_pSemaphore = new CSemaphore(); + + m_ObjectCollection.Add(m_pEventObject); + m_ObjectCollection.Add(m_pSemaphore); + + m_Queue = new void*[MaxCount]; + m_CurrentHead = 0; + m_CurrentTail = 0; + m_CurrentCount = 0; +} + +CSemaphoreQueue::~CSemaphoreQueue() +{ + delete m_pEventObject; + delete m_pSemaphore; + delete[] m_Queue; +} + +bool CSemaphoreQueue::AddTail(void *pObject) +{ + bool result = false; + CLockCS LocalCSLock(m_CSLock); + AddToQueueTail(pObject); + result = m_pSemaphore->Release(1); + + if (!result) { + // Error : use ::GetLastError for cause of error + RemoveFromQueueTail(); // Not really necessary but keep, + // everything's gone pear-shaped anyway + } + + return result; +} + +RemoveResult CSemaphoreQueue::RemoveHead(void **ppObject, size_t mSecTimeout) +{ + CWaitableObject *pWaitableObject = m_ObjectCollection.Wait(mSecTimeout); + + if (pWaitableObject == m_pEventObject) { + return REMOVE_CANCEL; + } else if (pWaitableObject == m_pSemaphore) { + CLockCS LocalCSLock(m_CSLock); + *ppObject = RemoveFromQueueHead(); // Remove pObject from pObjectQueue head + return REMOVE_SUCCESS; + } else if (NULL == pWaitableObject) { + return REMOVE_TIMEOUT;; + } else { + // Should never occur + assert(false); + return REMOVE_CANCEL;; + } +} + +void CSemaphoreQueue::SignalEvent() +{ + CEventObject *pEvent = m_pEventObject; + pEvent->SetEvent(); +} + +void CSemaphoreQueue::IncrementHead() +{ + ++m_CurrentHead; + + if (m_CurrentHead == m_MaximumCount) { + m_CurrentHead = 0; + } +} + +void CSemaphoreQueue::IncrementTail() +{ + ++m_CurrentTail; + + if (m_CurrentTail == m_MaximumCount) { + m_CurrentTail = 0; + } +} + +void CSemaphoreQueue::AddToQueueTail(void *pObject) +{ + m_Queue[m_CurrentTail] = pObject; + IncrementTail(); +} + +void *CSemaphoreQueue::RemoveFromQueueHead() +{ + void *Object; + Object = m_Queue[m_CurrentHead]; + IncrementHead(); + return Object; +} + +// Next 2 functions not really necessary - for error case only +void CSemaphoreQueue::DecrementTail() +{ + if (m_CurrentTail == 0) { + m_CurrentTail = m_MaximumCount - 1; + } else { + --m_CurrentTail; + } +} + +void CSemaphoreQueue::RemoveFromQueueTail() +{ + DecrementTail(); + m_Queue[m_CurrentTail] = 0; +} |