Skip to content

Instantly share code, notes, and snippets.

@shanewfx
Created March 10, 2012 00:09
Show Gist options
  • Save shanewfx/2009416 to your computer and use it in GitHub Desktop.
Save shanewfx/2009416 to your computer and use it in GitHub Desktop.
Loop Queue
// CQueue
//
// Implements a simple Queue ADT. The queue contains a finite number of
// objects, access to which is controlled by a semaphore. The semaphore
// is created with an initial count (N). Each time an object is added
// a call to WaitForSingleObject is made on the semaphore's handle. When
// this function returns a slot has been reserved in the queue for the new
// object. If no slots are available the function blocks until one becomes
// available. Each time an object is removed from the queue ReleaseSemaphore
// is called on the semaphore's handle, thus freeing a slot in the queue.
// If no objects are present in the queue the function blocks until an
// object has been added.
#define DEFAULT_QUEUESIZE 2
template <class T> class CQueue {
private:
HANDLE hSemPut; // Semaphore controlling queue "putting"
HANDLE hSemGet; // Semaphore controlling queue "getting"
CRITICAL_SECTION CritSect; // Thread seriallization
int nMax; // Max objects allowed in queue
int iNextPut; // Array index of next "PutMsg"
int iNextGet; // Array index of next "GetMsg"
T *QueueObjects; // Array of objects (ptr's to void)
void Initialize(int n) {
iNextPut = iNextGet = 0;
nMax = n;
InitializeCriticalSection(&CritSect);
hSemPut = CreateSemaphore(NULL, n, n, NULL);
hSemGet = CreateSemaphore(NULL, 0, n, NULL);
QueueObjects = new T[n];
}
public:
CQueue(int n) {
Initialize(n);
}
CQueue() {
Initialize(DEFAULT_QUEUESIZE);
}
~CQueue() {
delete [] QueueObjects;
DeleteCriticalSection(&CritSect);
CloseHandle(hSemPut);
CloseHandle(hSemGet);
}
T GetQueueObject() {
int iSlot;
T Object;
LONG lPrevious;
// Wait for someone to put something on our queue, returns straight
// away is there is already an object on the queue.
//
WaitForSingleObject(hSemGet, INFINITE);
EnterCriticalSection(&CritSect);
iSlot = iNextGet++ % nMax;
Object = QueueObjects[iSlot];
LeaveCriticalSection(&CritSect);
// Release anyone waiting to put an object onto our queue as there
// is now space available in the queue.
//
ReleaseSemaphore(hSemPut, 1L, &lPrevious);
return Object;
}
void PutQueueObject(T Object) {
int iSlot;
LONG lPrevious;
// Wait for someone to get something from our queue, returns straight
// away is there is already an empty slot on the queue.
//
WaitForSingleObject(hSemPut, INFINITE);
EnterCriticalSection(&CritSect);
iSlot = iNextPut++ % nMax;
QueueObjects[iSlot] = Object;
LeaveCriticalSection(&CritSect);
// Release anyone waiting to remove an object from our queue as there
// is now an object available to be removed.
//
ReleaseSemaphore(hSemGet, 1L, &lPrevious);
}
};
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment