154 lines
5.0 KiB
C
154 lines
5.0 KiB
C
|
#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
|