summaryrefslogtreecommitdiff
path: root/source/api_wrappers/linux/CSemaphoreQueue.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'source/api_wrappers/linux/CSemaphoreQueue.cpp')
-rw-r--r--source/api_wrappers/linux/CSemaphoreQueue.cpp121
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;
+}