CMNetwork/inc/hgl/network/SocketManageThread.h

154 lines
5.0 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#ifndef HGL_NETWORK_SOCKET_MANAGE_THREAD_INCLUDE
#define HGL_NETWORK_SOCKET_MANAGE_THREAD_INCLUDE
#include<hgl/network/SocketManage.h>
#include<hgl/thread/Thread.h>
#include<hgl/thread/SwapData.h>
namespace hgl
{
namespace network
{
/**
* 简单的Socket管理器线程
*/
template<typename USER_ACCEPT> class SocketManageThread:public Thread
{
public:
using AcceptSocketList=List<USER_ACCEPT *>; ///<工作对象列表定义
protected:
SocketManage *sock_manage;
protected:
SemSwapData<AcceptSocketList> join_list; ///<待添加的Socket对象列表
SemSwapData<AcceptSocketList> unjoin_list; ///<待移出的Socket对象列表
virtual void OnSocketClear(USER_ACCEPT *us){delete us;} ///<Socket清理事件
virtual void OnSocketError(USER_ACCEPT *us){OnSocketClear(us);} ///<Socket出错处理事件
template<typename ST>
void ClearAcceptSocketList(ST &sl)
{
const int count=sl.GetCount();
USER_ACCEPT **us=sl.GetData();
for(int i=0;i<count;i++)
{
OnSocketClear(*us);
++us;
}
sl.ClearData();
}
virtual bool Join(USER_ACCEPT *us){return sock_manage->Join(us);} ///<单个工作对象接入处理函数
virtual bool Unjoin(USER_ACCEPT *us){return sock_manage->Unjoin(us);} ///<单个工作对象退出处理函数
/**
*处理要接入的工作对象列表
*/
void ProcJoinList()
{
AcceptSocketList &usl=join_list.GetReceive();
const int count=usl.GetCount();
USER_ACCEPT **us=usl.GetData();
for(int i=0;i<count;i++)
{
Join(*us);
++us;
}
usl.ClearData();
}
/**
* 处理要退出的工作对象列表
*/
void ProcUnjoinList()
{
AcceptSocketList &usl=unjoin_list.GetReceive();
const int count=usl.GetCount();
USER_ACCEPT **us=usl.GetData();
for(int i=0;i<count;i++)
{
Unjoin(*us);
++us;
}
usl.ClearData();
}
public:
SocketManageThread(SocketManage *sm)
{
sock_manage=sm;
}
virtual ~SocketManageThread()
{
SAFE_CLEAR(sock_manage);
}
virtual void ProcEndThread() override
{
ClearAcceptSocketList(join_list.GetReceive());
join_list.Swap();
ClearAcceptSocketList(join_list.GetReceive());
sock_manage->Clear();
//unjoin_list中的理论上都已经在wo_list/join_list里了所以不需要走Clear直接清空列表
unjoin_list.GetReceive().ClearData();
unjoin_list.Swap();
unjoin_list.GetReceive().ClearData();
}
virtual bool Execute() override
{
if(join_list.TrySemSwap())
ProcJoinList();
if(unjoin_list.TrySemSwap())
ProcUnjoinList();
sock_manage->Update(0.1); //这里写0.1秒只是为了不卡住主轮循。这是个错误的设计未来要将epoll(recv)完全独立一个线程跑
const auto &error_set=sock_manage->GetErrorSocketSet();
USER_ACCEPT **us=(USER_ACCEPT **)error_set.GetData();
for(int i=0;i<error_set.GetCount();i++)
{
OnSocketError(*us);
++us;
}
return(true);
}
public:
virtual AcceptSocketList & JoinBegin(){return join_list.GetPost();} ///<开始添加要接入的Socket对象
virtual void JoinEnd() ///<结束添加要接入的Socket对象
{
join_list.ReleasePost();
join_list.PostSem();
}
virtual AcceptSocketList & UnjoinBegin(){return unjoin_list.GetPost();}///<开始添加要退出的Socket对象
virtual void UnjoinEnd() ///<结束添加要退出的Socket对象
{
unjoin_list.ReleasePost();
unjoin_list.PostSem();
}
};//template<typename USER_ACCEPT> class SocketManageThread:public Thread
}//namespace network
}//namespace hgl
#endif//HGL_NETWORK_SOCKET_MANAGE_THREAD_INCLUDE