summaryrefslogtreecommitdiff
path: root/gobi-api/GobiAPI_1.0.40/Core/SyncQueue.h
diff options
context:
space:
mode:
Diffstat (limited to 'gobi-api/GobiAPI_1.0.40/Core/SyncQueue.h')
-rwxr-xr-xgobi-api/GobiAPI_1.0.40/Core/SyncQueue.h419
1 files changed, 419 insertions, 0 deletions
diff --git a/gobi-api/GobiAPI_1.0.40/Core/SyncQueue.h b/gobi-api/GobiAPI_1.0.40/Core/SyncQueue.h
new file mode 100755
index 0000000..7c62e3f
--- /dev/null
+++ b/gobi-api/GobiAPI_1.0.40/Core/SyncQueue.h
@@ -0,0 +1,419 @@
+/*===========================================================================
+FILE:
+ SyncQueue.h
+
+DESCRIPTION:
+ Declaration/Implementation of cSyncQueue class
+
+PUBLIC CLASSES AND METHODS:
+ cSyncQueue
+ Synchronized shareable (across multiple threads) queue of
+ structures with event notifications
+
+Copyright (c) 2011, Code Aurora Forum. All rights reserved.
+
+Redistribution and use in source and binary forms, with or without
+modification, are permitted provided that the following conditions are met:
+ * Redistributions of source code must retain the above copyright
+ notice, this list of conditions and the following disclaimer.
+ * Redistributions in binary form must reproduce the above copyright
+ notice, this list of conditions and the following disclaimer in the
+ documentation and/or other materials provided with the distribution.
+ * Neither the name of Code Aurora Forum nor
+ the names of its contributors may be used to endorse or promote
+ products derived from this software without specific prior written
+ permission.
+
+
+THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
+ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
+LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
+INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
+CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
+ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGE.
+===========================================================================*/
+
+//---------------------------------------------------------------------------
+// Pragmas
+//---------------------------------------------------------------------------
+#pragma once
+
+//---------------------------------------------------------------------------
+// Include Files
+//---------------------------------------------------------------------------
+#include <deque>
+#include "Event.h"
+
+//---------------------------------------------------------------------------
+// Definitions
+//---------------------------------------------------------------------------
+
+/*=========================================================================*/
+// Class cSyncQueue
+/*=========================================================================*/
+template <class tElementType> class cSyncQueue
+{
+ public:
+ // (Inline) Constructor
+ cSyncQueue(
+ ULONG maxElements,
+ bool bSignalEvent = false )
+ : mSignature( (ULONG)eSYNC_QUEUE_SIG ),
+ mSignalEvent(),
+ mbSignalEvent( bSignalEvent ),
+ mMaxElements( maxElements ),
+ mTotalElements( 0 )
+ {
+ // Create sync CS
+ int nRet = pthread_mutex_init( &mSyncSection, NULL );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to init sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return;
+ }
+ };
+
+ // (Inline) Destructor
+ ~cSyncQueue()
+ {
+ if (IsValid() == false)
+ {
+ ASSERT( (PVOID)"Double deletion detected in ~cSyncQueue" == 0 );
+ }
+ else
+ {
+ EmptyQueue();
+
+ mSignature = 0;
+ int nRet = pthread_mutex_destroy( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to destroy sync mutex."
+ " Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return;
+ }
+ }
+
+ };
+
+ // (Inline) Add an element to the queue
+ bool AddElement( const tElementType & elem )
+ {
+ // Assume failure
+ bool bRC = false;
+ if (IsValid() == false)
+ {
+ ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
+ return bRC;
+ }
+
+ int nRet = pthread_mutex_lock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+
+ // Are we out of space?
+ if ((ULONG)mElementDeque.size() >= mMaxElements)
+ {
+ // Yes, drop oldest element
+ mElementDeque.pop_front();
+ }
+
+ // Add new item to the queue
+ mElementDeque.push_back( elem );
+ mTotalElements++;
+
+ // Set event?
+ if (mbSignalEvent == true)
+ {
+ // Signal index of event
+ nRet = mSignalEvent.Set( mTotalElements - 1 );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to signal. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+ }
+
+ // Success!
+ bRC = true;
+
+ nRet = pthread_mutex_unlock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+
+ return bRC;
+ };
+
+ // (Inline) Add an element to the queue returning the index of
+ // the element
+ bool AddElement(
+ const tElementType & elem,
+ ULONG & idx )
+ {
+ // Assume failure
+ bool bRC = false;
+ if (IsValid() == false)
+ {
+ ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
+ return bRC;
+ }
+
+ int nRet = pthread_mutex_lock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+
+ // Are we out of space?
+ if ((ULONG)mElementDeque.size() >= mMaxElements)
+ {
+ mElementDeque.pop_front();
+ }
+
+ // Add new item to the queue
+ mElementDeque.push_back( elem );
+ idx = mTotalElements++;
+
+ // Set event?
+ if (mbSignalEvent == true)
+ {
+ // Signal index of event
+ nRet = mSignalEvent.Set( mTotalElements - 1 );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to signal. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+ }
+
+ // Success!
+ bRC = true;
+
+ nRet = pthread_mutex_unlock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+
+ return bRC;
+ };
+
+ // (Inline) Return given element in the queue
+ bool GetElement(
+ ULONG idx,
+ tElementType & elem ) const
+ {
+ // Assume failure
+ bool bRC = false;
+ if (IsValid() == false)
+ {
+ ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
+ return bRC;
+ }
+
+ int nRet = pthread_mutex_lock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+
+ // Is this a current element index?
+ ULONG expiredIndices = mTotalElements - (ULONG)mElementDeque.size();
+ if (idx >= expiredIndices)
+ {
+ // Yes, grab it from the deque
+ idx -= expiredIndices;
+ if (idx < (ULONG)mElementDeque.size())
+ {
+ elem = mElementDeque[idx];
+ bRC = true;
+ }
+ }
+
+ nRet = pthread_mutex_unlock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+
+ return bRC;
+ };
+
+ // (Inline) Empty element queue
+ bool EmptyQueue()
+ {
+ // Assume failure
+ bool bRC = false;
+ if (IsValid() == false)
+ {
+ ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
+ return bRC;
+ }
+
+ int nRet = pthread_mutex_lock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+
+
+ mElementDeque.clear();
+ mTotalElements = 0;
+
+ nRet = pthread_mutex_unlock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return false;
+ }
+
+ bRC = true;
+ return bRC;
+ };
+
+ // (Inline) Return the number of queued elements
+ ULONG GetQueueCount() const
+ {
+ ULONG elems = 0;
+ if (IsValid() == false)
+ {
+ ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
+ return elems;
+ }
+
+ int nRet = pthread_mutex_lock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return 0;
+ }
+
+ elems = (ULONG)mElementDeque.size();
+
+ nRet = pthread_mutex_unlock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return 0;
+ }
+
+ return elems;
+ };
+
+ // (Inline) Return the total number of elements added to queue
+ ULONG GetTotalCount() const
+ {
+ ULONG elems = 0;
+ if (IsValid() == false)
+ {
+ ASSERT( (PVOID)"Bad cSyncQueue object detected" == 0 );
+ return elems;
+ }
+
+ int nRet = pthread_mutex_lock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to lock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return 0;
+ }
+
+ elems = mTotalElements;
+
+ nRet = pthread_mutex_unlock( &mSyncSection );
+ if (nRet != 0)
+ {
+ TRACE( "SyncQueue: Unable to unlock sync mutex. Error %d: %s\n",
+ nRet,
+ strerror( nRet ) );
+ return 0;
+ }
+
+ return elems;
+ };
+
+ // (Inline) Return the signal event
+ cEvent & GetSignalEvent() const
+ {
+ return mSignalEvent;
+ };
+
+ // (Inline) Is this sync queue valid?
+ bool IsValid() const
+ {
+ return (mSignature == (ULONG)eSYNC_QUEUE_SIG);
+ };
+
+ protected:
+ // Object signature
+ enum eClassConstants
+ {
+ eSYNC_QUEUE_SIG = 0x1799A2BC
+ };
+
+ /* Object signature */
+ ULONG mSignature;
+
+ /* Multithreaded mutex type */
+ mutable pthread_mutex_t mSyncSection;
+
+ /* Signal event, set everytime an element is added (if configured) */
+ mutable cEvent mSignalEvent;
+
+ /* Use above signal event? */
+ bool mbSignalEvent;
+
+ /* Maximum number of elements to add to the deque */
+ ULONG mMaxElements;
+
+ /* Total number of elements added to the deque */
+ ULONG mTotalElements;
+
+ /* Element queue */
+ std::deque <tElementType> mElementDeque;
+};