ULRE/inc/hgl/thread/DataPost.h

157 lines
2.9 KiB
C
Raw Normal View History

2018-11-27 15:43:32 +08:00
#ifndef HGL_THREAD_DATA_POST_INCLUDE
#define HGL_THREAD_DATA_POST_INCLUDE
#include<hgl/thread/ThreadMutex.h>
#include<hgl/thread/Semaphore.h>
#include<hgl/type/Stack.h>
namespace hgl
{
/**
* 线<br>
* 线
*/
template<typename T> class DataPost
{
protected:
List<T *> data_list[2];
int post_index,recv_index;
int recv_offset;
ThreadMutex post_lock,recv_lock;
protected:
void _Swap()
{
if(recv_index){recv_index=0;post_index=1;}
else{recv_index=1;post_index=0;}
recv_offset=0;
}
public:
DataPost()
{
post_index=0;
recv_index=1;
recv_offset=0;
}
virtual ~DataPost()=default;
/**
*
*/
void Post(T *obj)
{
if(!obj)return;
post_lock.Lock();
data_list[post_index].Add(obj);
post_lock.Unlock();
}
/**
*
*/
void Post(T **obj,int count)
{
if(!obj)return;
post_lock.Lock();
data_list[post_index].Add(obj,count);
post_lock.Unlock();
}
public:
/**
*
*/
T *Receive()
{
T *obj=nullptr;
recv_lock.Lock();
int count=data_list[recv_index].GetCount();
if(recv_offset<count)
{
obj=*(data_list[recv_index].GetData()+recv_offset);
++recv_offset;
}
else
{
data_list[recv_index].ClearData(); //清空接收区的数据
post_lock.Lock();
_Swap();
post_lock.Unlock();
count=data_list[recv_index].GetCount();
if(count>0) //如果换出来的区有数据
{
obj=*(data_list[recv_index].GetData()+recv_offset);
++recv_offset;
}
}
recv_lock.Unlock();
return obj;
}
};//template<typename T> class DataPost
/**
* 访
*/
template<typename T> class SemDataPost:public DataPost<T>
{
Semaphore sem;
public:
using DataPost<T>::DataPost;
~SemDataPost()=default;
/**
*
* @param count
*/
void PostSem(int count=1)
{
sem.Post(count);
}
/**
*
* @param time_out
*/
T *WaitSemReceive(const double time_out=5)
{
if(!sem.Acquire(time_out))
return(nullptr);
return this->Receive();
}
/**
*
*/
T *TrySemReceive()
{
if(!sem.TryAcquire())
return(nullptr);
return this->Receive();
}
};//template<typename T> class SemDataPost:public DataPost<T>
}//namespace hgl
#endif//HGL_THREAD_DATA_POST_INCLUDE