⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 basequeue.h

📁 symbian平台S60_2nd_FP2_SC rtp实现
💻 H
字号:
#ifndef __BaseQueue_H__
#define __BaseQueue_H__

#include "ResourceBase.h"
const int constDEFAULTQUEUESIZE = 512 ;

template <class T> class BaseQueue
{
	T **data;
	int size;

	T **head;
	T **tail;
	T **dataend;

	CTSemaphore  pOccupiedSema;
	CTCriticalSection m_lock;

public:
	BaseQueue(int aSize = constDEFAULTQUEUESIZE, int isMulti = 1);
	//Constructor, aSize=buffer size, isMulti=true means there are mutliple producer/consumer.
	~BaseQueue();

	void Put(T &newData);
	//Put a new data into queue, if queue is occupied that block until not occupied.
	void Get(T &buf);
	//Get a data from queue, if queue is empty that block until not empty.
	int	 Remove();
	void RemoveAll() ; 
	
	int  TryPut(T &newData);
	//Put a new data into queue, if queue is occupied that return -1 else return 0.
	int  TryGet(T &buf);
	//Get a data from queue, if queue is empty that return -1 else return 0.
//	int  TryRemove();	

	int PutHead(T &newData);
	//Put a new data into queue head, if queue is occupied that return -1 else return 0.
	int TryPutHead(T &newData);

	int	 Peek(T &buf);

	int  GetCount();
	int  IsEmpty()  ; 
	int  IsOccupied() ;  

private:
	inline int  InnerGetCount();
	inline int  InnerPut(T &newData);
	inline void InnerGet(T &buf);

};

//  Queue:
//         +----+----+----+----+----+----+----+----+----+
//         |T*  |T*  |    |    |    |    |    |    |    |
//         +----+----+----+----+----+----+----+----+----+
//         ^              ^              ^               ^
//         data           head           tail            dataend
//
//                        <---- count --->
//         <---------------- size ----------------->
//         <-------------- buffer size ----------------->
//
//         IsEmpty: if head=tail
//         IsOccupied: if tail=head-1

//////////////////////////////////////////////////////
//Purpose      : 构造函数
//Input Paras  : 
//				aSize   指定队列的大小
//				isMulti 已经废除,全部都是多线程的处理方式,
//				不是多线程的话,请使用std::queue
//Output Paras : 无
//Return Value : 无
//Relations    : 无
///////////////////////////////////////////////////////
template <class T>
BaseQueue< T >::BaseQueue(int aSize, int /*isMulti*/) :
#ifdef WIN32
	pOccupiedSema(0,aSize)
#else
	pOccupiedSema(0)
#endif
{
	size = aSize>0?aSize:1;


	typedef T* TP;
	data = new TP [size+1];
	assert(data);
	for(int i=0; i<=size; i++)
		data[i]=0;
	tail = head = data;
	dataend = data+size+1;
}


//////////////////////////////////////////////////////
//Purpose      : 析构函数,释放全部队列资源
//Input Paras  : 无
//Output Paras : 无
//Return Value : 无
//Relations    : 无
///////////////////////////////////////////////////////
template <class T>
BaseQueue< T >::~BaseQueue()
{
	for(int i = 0; i<=size; i++)
	{
		delete data[i];
		data[i] = 0 ;
	}
	delete [] data;	
}


template <class T>
int  BaseQueue< T >::GetCount()
{
	int count=0;

	m_lock.Lock();
	count=InnerGetCount();
	m_lock.Unlock();
	
	return count;
}


template <class T>
int  BaseQueue< T >::IsEmpty() 
{
	int ret=0;

	m_lock.Lock();
	ret = (InnerGetCount() == 0 );
	m_lock.Unlock();

	return ret ;
}

template <class T>
int  BaseQueue< T >::IsOccupied() 
{
	int ret=0;

	m_lock.Lock();
	ret = (InnerGetCount() == size );
	m_lock.Unlock();

	return ret ;
}


//////////////////////////////////////////////////////
//Purpose      : put一个元素到队列(末尾)
//Input Paras  : 
//				newData 要放到队列中的元素
//Output Paras : 无
//Return Value : 无
//Relations    : newData的类必须支持复制
//Note		   : 此函数在队列满的情况下,不执行put动作,参考TryPut函数
///////////////////////////////////////////////////////
template <class T>
void BaseQueue< T >::Put(T &newData)
{
	int ret=-1;

	m_lock.Lock();
	if( InnerGetCount() < size )
	{
		ret = InnerPut(newData);
		pOccupiedSema.Post();
	}
	m_lock.Unlock();

	return ;
}

//////////////////////////////////////////////////////
//Purpose      : 尝试put一个元素到队列(尾部),
//				 如果队列已经满,则返回-1,否则返回0
//Input Paras  : 
//				newData 要put的元素
//Output Paras : 
//				-1 队列满
//				 0 成功
//Return Value : 
//Relations    : newData的类必须支持复制
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::TryPut(T &newData)
{
	int ret=-1;

	m_lock.Lock();
	if( InnerGetCount() < size )
	{
		ret = InnerPut(newData);
		pOccupiedSema.Post();
	}
	m_lock.Unlock();

	return ret;
}


//////////////////////////////////////////////////////
//Purpose      : put一个元素到对列头
//Input Paras  : 
//				newData 要放到队列中的元素
//Output Paras : 无
//Return Value : 无
//Relations    : newData的类必须支持复制
//Note		   : 此函数在队列满的情况下,不执行put动作,参考TryPutHead函数
///////////////////////////////////////////////////////
template <class T>
int  BaseQueue< T >::PutHead(T &newData)
{
	int ret=-1;

	m_lock.Lock();

	if(  InnerGetCount() < size )
	{
		T *tmpdata = new T ;
		if( tmpdata ) 
		{
			*tmpdata = newData;

			if( head == data )
				head = data+size ;
			else 
				head -- ;
		
			*head = tmpdata;
			pOccupiedSema.Post();

			ret = 0 ;
		}
	}

	m_lock.Unlock();

	return ret ;
}


//////////////////////////////////////////////////////
//Purpose      : 尝试put一个元素到队列头,如果队列已经满,则返回-1,否则返回0
//Input Paras  : 
//				newData 要put的元素
//Output Paras : 
//				-1 队列满
//				 0 成功
//Return Value : 
//Relations    : newData的类必须支持复制
///////////////////////////////////////////////////
template <class T>
int  BaseQueue< T >::TryPutHead(T &newData)
{
	int ret=-1;

	m_lock.Lock();

	if(  InnerGetCount() < size )
	{
		T	*tmpdata = new T ;
		if( tmpdata ) 
		{
			*tmpdata = newData;

			if( head == data )
				head = data+size ;
			else 
				head -- ;
		
			*head = tmpdata;
			pOccupiedSema.Post();
			ret = 0 ;
		}
	}

	m_lock.Unlock();

	return ret ;
}


//////////////////////////////////////////////////////
//Purpose      : 取得一个队列的当前元素,如果队列是空的话,那么一直等待
//Input Paras  : 无
//Output Paras : 
//				buf 返回取得的元素
//Return Value : 无
//Relations    : buf的类必须支持复制
///////////////////////////////////////////////////////
template <class T>
void BaseQueue< T >::Get(T &buf)
{
	pOccupiedSema.Wait();
	m_lock.Lock();	
	InnerGet(buf);
	m_lock.Unlock();
}


//////////////////////////////////////////////////////
//Purpose      : 尝试取得一个队列的当前元素
//Input Paras  : 无
//Output Paras : 
//				buf 返回取得的元素
//Return Value : 
//				-1 表示当前队列是空的
//				 0 成功
//Relations    : buf的类必须支持复制
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::TryGet(T &buf)
{
/*	if( IsEmpty() )
		return -1;

	pOccupiedSema.Wait();

	m_lock.Lock();	
	InnerGet(buf);
	m_lock.Unlock();

	return 0 ;
*/

   int ret=-1;

   m_lock.Lock();
   if( InnerGetCount() > 0 )
   {
		pOccupiedSema.Wait();
		InnerGet(buf);
		ret = 0 ;
   }
   m_lock.Unlock();

   return ret;
}



//////////////////////////////////////////////////////
//Purpose      : 查看一个队列的当前元素
//Input Paras  : 无
//Output Paras : 
//				buf 返回取得的元素
//Return Value : 
//				-1 表示当前队列是空的
//				 0 成功
//Relations    : buf的类必须支持复制
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::Peek(T & buf)
{
	int ret=-1;

	m_lock.Lock();
	if( InnerGetCount() )
	{
		buf = **head; 
		ret = 0 ;
	}
	m_lock.Unlock();

	return ret;
}

//////////////////////////////////////////////////////
//Purpose      : 删除当前队列头元素
//Input Paras  : 无
//Output Paras : 无
//Return Value : 
//				-1 队列是空的
//				 0 删除成功
//Relations    : 无
///////////////////////////////////////////////////////
template <class T>
int BaseQueue< T >::Remove()
{
	T tmp;
	TryGet( tmp ) ;

	return 0 ;
}


template <class T>
void BaseQueue< T >::RemoveAll() 
{ 
	T tmp;

	for(;;)
	{
		if( TryGet(tmp) != 0 )
			break;
	}

}


///////////private/////////////////////////

template <class T>
int  BaseQueue< T >::InnerGetCount()
{
	if (tail>=head)
		return ( int )(tail-head);
	else
		return ( int )(size+1-(head-tail));	
}

template <class T>
inline void  BaseQueue< T >::InnerGet(T &buf)
{
	buf = **head; // operator =
	T* prev = *head;

	delete prev;
	*head = NULL;
	head++;
	if (head>=dataend)
		head = data;
}


template <class T>
inline int BaseQueue< T >::InnerPut(T &newData)
{
	T *tmpdata = new T;

	if( tmpdata )
	{
		*tmpdata = newData ;
		*tail = tmpdata ;

		tail++;
		if (tail>=dataend)
			tail = data;	

		return 0 ;
	}
	return -1;
}

#endif

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -