Source: classlib/include/classlib/squeue.h
|
|
|
|
// squeue.h : coda generica con controllo multithread
// Nicola De Nisco S.Lucia di Piave, 8 Giugno 1998
#if !defined( __CLASSLIB_SQUEUE_H )
#define __CLASSLIB_SQUEUE_H
#if !defined( __CLASSLIB_QUEUES_H )
#include "classlib/queues.h"
#endif // __CLASSLIB_DEFS_H
#include "classlib/mtsync.h"
template class TISTQueueIterator;
/**
Thread safe queue.
This class implements a thread safe queue ready to use
in multitread application. The queue have a CriticalSection (see)
for syncronization of insertion end extraction from the queue.
It can notify a waiting thread when new item are inserted into the queue
(see the LockIfEmpty method).
The internal implementation is a linked list queue.
*/
template class TISTQueue :
private TIQueueAsDoubleList
{
typedef TIQueueAsDoubleList Parent;
public:
//enum DeleteType { NoDelete, DefDelete, Delete };
friend class TISTQueueIterator;
/**
Construct the queue and the semaphore in non blocking state
*/
TISTQueue() : evitem( FALSE, TRUE )
{
evitem.ResetEvent();
}
/**
Get an element from the queue. The get operation request the lock
of a CriticalSection (see) to proceed. The calling thread will be locked
if another thread is accessing another lock method.
*/
T *Get()
{
csec.Lock();
T* ptTmp = Parent::Get();
if( IsEmpty() )
evitem.ResetEvent();
csec.Unlock();
return ptTmp;
}
/**
Put an element into the queue. The put operation request the lock
of a CriticalSection (see) to proceed. The calling thread will be locked
if another thread is accessing another lock method.
*/
void Put( T *t )
{
csec.Lock();
Parent::Put( t );
evitem.SetEvent();
csec.Unlock();
}
/**
Destroy all elements into the queue. The flush operation request the lock
of a CriticalSection (see) to proceed. The calling thread will be locked
if another thread is accessing another lock method.
*/
void Flush()
{
csec.Lock();
Parent::Flush();
evitem.ResetEvent();
csec.Unlock();
}
/**
Detach an element from the queue. The detach operation request the lock
of a CriticalSection (see) to proceed. The calling thread will be locked
if another thread is accessing another lock method.
*/
int Detach( T *t )
{
csec.Lock();
int rv = Parent::Detach(t);
if( IsEmpty() )
evitem.ResetEvent();
csec.Unlock();
return rv;
}
typedef void (*IterFunc)(T&, void *);
typedef int (*CondFunc)(const T&, void *);
/** auto iterator: use an iterator function calling it for every element of the array;
the function must have a prototype like this: void iterFunc(T&, void* args);
The operation request the lock
of a CriticalSection (see) to proceed. The calling thread will be locked
if another thread is accessing another lock method. */
void ForEach( IterFunc iter, void *args )
{
csec.Lock();
Parent::ForEach( iter, args );
csec.Unlock();
}
/** auto iterator: use a test function calling it for every element of the array;
the function must have a prototype like this: int testFunc(const T&, void* args);
the function must return 0 if the test fail, != 0 if test is ok; the first element
tested successful will be returned or NULL if no elements is ok.
The operation request the lock
of a CriticalSection (see) to proceed. The calling thread will be locked
if another thread is accessing another lock method. */
T *FirstThat( CondFunc cond, void *args )
{
csec.Lock();
T* rv = Parent::FirstThat( cond, args );
csec.Unlock();
return rv;
}
/** auto iterator: use a test function calling it for every element of the array;
the function must have a prototype like this: int testFunc(const T&, void* args);
the function must return 0 if the test fail, != 0 if test is ok; the last element
tested successful will be returned or NULL if no elements is ok.
The operation request the lock
of a CriticalSection (see) to proceed. The calling thread will be locked
if another thread is accessing another lock method. */
T *LastThat( CondFunc cond, void *args )
{
csec.Lock();
T* rv = Parent::LastThat( cond, args );
csec.Unlock();
return rv;
}
Parent::Peek;
Parent::IsEmpty;
Parent::GetItemsInContainer;
void LockIfEmpty()
{
CSingleLock(&evitem, TRUE);
}
protected:
CCriticalSection csec;
CEvent evitem;
};
/**
The TISTQueue iterator.
This iterator try to acquire the CriticalSection of the queue.
The calling thread will be locked if another thread is accessing another lock method.
IMPORTANT NOTE: the iterator destructor release the lock.
The queue will be locked for the complete lifecicle of the Iterator instance.
*/
template class TISTQueueIterator :
public TIQueueAsDoubleListIterator
{
public:
TISTQueueIterator( TISTQueue& q ) :
TIQueueAsDoubleListIterator(q)
{
ptQueue = &q;
ptQueue->csec.Lock();
}
virtual ~TISTQueueIterator()
{
ptQueue->csec.Unlock();
}
private:
TISTQueue* ptQueue;
};
#endif // __CLASSLIB_SQUEUE_H
Generated by: nicola on gulliver.wadahome.it on Sun May 25 13:54:34 2003, using kdoc 2.0a53. |