一个包到从共享内存到GS流程
上次说到一个包从共享内存池取到一个包之后放入共享队列中
hr = m_spShareMemInter->pushA(sd);
看看GS这边是如何取包的
主线程创建了一个子线程
void GameServer::ProcessThread()
{
try
{
ProcessThreadTry();
}
catch (...)
{
DWORD dwErrno = GetLastError();
MessageBox(NULL, L"GameServer::process_thread异常", L"异常", MB_OK);
}
}
void GameServer::ProcessThreadTry()
{
int nCount = 0;
packet Pkt;
Pkt.data = new char[1024 * 100];//事先分配内存
I_TimerFactory* pTimeFactory = GetPlug(TimerFactory);
for (;;)
{
ProcMapSendData();//map发过来的数据
m_spAsynDBC->Drive();//数据库回调
bool bRcvDataRet = ProcessLoop(Pkt);//网络层的数据,现在只看这个
ProcMapSendData();
}
//...(下面还有很多,暂时不看)
}
if(!m_spShareMemInter->popB(tmpShareData))来看看这个popB的实现
bool shareMemInterOneway::popOut(shareData& sd)
{
{
if(m_ShareMemQue->size() == 0)//m_ShareMemQue就是交互的真正的队列,注意他里面保存一个内存池中的地址
return false;
}
{
scoped_lock<interprocess_mutex> lock(m_mem镜像->mutex);//进程锁
if(m_ShareMemQue->size() == 0)
return false;
auto sd2 = m_ShareMemQue->front();
m_ShareMemQue->pop_front();
sd.size = sd2.size;
sd.channel_id = sd2.channel_id;
sd.is_data = sd2.is_data;
if(sd2.is_data)
{
try
{
memcpy(sd.data, m_ProcessMemPool.convertAdd(sd2.total_size, sd2.index), sd.size);//从内存池中拷贝出来
}
catch(...)
{
MessageBox(NULL, L"shareMemInterOneway::popB", L"1ooo", MB_OK);
}
}
m_ProcessMemPool.pushPkt(sd2);//归还内存池中的内存
}
return true;
}
bool GameServer::ProcessLoop(packet& rPkt)
{
if(false == m_spDataLayer->Recv(rPkt))
return true;//没数据了
if(rPkt.is_data)
{
if(!rPkt.data)
return false;
GameChannel* pGC = m_vecChannel[rPkt.channel_id];//根据channelid确定是哪个channel,一个玩家对应一个channel
if(pGC)
pGC->OnReceiveData(rPkt.data, rPkt.size);
m_LiveMgr.OnLive(rPkt.channel_id);
}
else//其他事件如连接断开,都是libevent事件
{
}
}
//一个包历经千辛万苦才打到服务器,对于到时怎么调用不同的函数,随后在看