CMCore/inc/hgl/thread/SwapData.h

241 lines
4.8 KiB
C
Raw Permalink Normal View History

2019-08-19 19:19:58 +08:00
#ifndef HGL_THREAD_SWAP_DATA_INCLUDE
#define HGL_THREAD_SWAP_DATA_INCLUDE
#include<hgl/thread/ThreadMutex.h>
#include<hgl/thread/Semaphore.h>
namespace hgl
{
/**
* 线<br>
* 线线线
*/
template<typename T> class SwapData
{
protected:
T data[2];
int post_index;
int recv_index;
ThreadMutex lock;
protected:
void _Swap()
{
if(recv_index){recv_index=0;post_index=1;}
else{recv_index=1;post_index=0;}
}
public:
SwapData()
{
recv_index=0;
post_index=1;
}
virtual ~SwapData()=default;
/**
* 访
*/
T &GetPost()
{
lock.Lock();
return data[post_index];
}
/**
* 线访
*/
void ReleasePost()
{
lock.Unlock();
}
/**
* 访
*/
T &GetReceive(){return data[recv_index];}
/**
*
*/
void Swap()
{
lock.Lock();
this->_Swap();
lock.Unlock();
}
/**
*
*/
bool TrySwap()
{
if(!lock.TryLock())
return(false);
this->_Swap();
lock.Unlock();
return(true);
}
#ifndef __APPLE__
/**
*
*/
bool WaitSwap(const double time_out)
{
if(!lock.WaitLock(time_out))
return(false);
this->_Swap();
lock.Unlock();
return(true);
}
#endif//__APPLE__
};//template<typename T> class SwapData
/**
* 访
*/
template<typename T> class SemSwapData:public SwapData<T>
{
Semaphore sem;
public:
using SwapData<T>::SwapData;
~SemSwapData()=default;
/**
*
* @param count
*/
void PostSem(int count=1)
{
sem.Post(count);
}
/**
*
* @param time_out
*/
bool WaitSemSwap(const double time_out=5)
{
if(!sem.Acquire(time_out))
return(false);
this->Swap();
return(true);
}
/**
*
*/
bool TrySemSwap()
{
if(!sem.TryAcquire())
return(false);
this->Swap();
return(true);
}
};//template<typename T> class SemSwapData:public SwapData<T>
/**
* SwapData模板自动释放Post工具模板
*/
template<typename T> class PostToSwapData
{
SwapData<T> *swap_data;
T *post;
public:
PostToSwapData(SwapData<T> *sd)
{
swap_data=sd;
if(swap_data)
post=&(swap_data->GetPost());
else
post=nullptr;
}
~PostToSwapData()
{
if(swap_data)
swap_data->ReleasePost();
}
T *operator ->(){return post;}
};//template<typename T> class PostToSwapData
/**
* SemSwapData模板自动释放Post工具模板
*/
template<typename T> class PostToSemSwapData
{
SemSwapData<T> *swap_data;
T *post;
public:
PostToSemSwapData(SemSwapData<T> *sd)
{
swap_data=sd;
if(swap_data)
post=&(swap_data->GetPost());
else
post=nullptr;
}
~PostToSemSwapData()
{
if(swap_data)
{
swap_data->ReleasePost();
swap_data->PostSem();
}
}
T *operator ->(){return post;}
};//template<typename T> class PostToSemSwapData
/**
* 使
*
* using EventQueue=Queue<int>;
* using MTEventQueue=SemSwapData<EventQueue>;
* using MTEventPost=PostToSemSwapData<EventQueue>;
*
* MTEventQueue mt_event_queue;
*
* :
* MTEventPost post(mt_event_queue);
*
* post.Push(1);
*
* :
* EventQueue &eq=mt_event_queue.GetPost();
*
* eq->Push(1);
*
* mt_event_queue.ReleasePost();
* mt_event_queue.PostSem();
*
*/
}//namespace hgl
#endif//HGL_THREAD_SWAP_DATA_INCLUDE