void SFMultiLogicDispatcher::MultiLogicProc(void* Args) { #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = static_cast<SFIOCPQueue<BasePacket>*>(Args); #else SFLockQueue<BasePacket>* pQueue = static_cast<SFLockQueue<BasePacket>*>(Args); #endif LogicEntry::GetInstance()->Initialize(); while (true) { BasePacket* pPacket = pQueue->Pop(-1); if (pPacket == nullptr) continue; if (pPacket->GetPacketType() == SFPACKET_SERVERSHUTDOWN) break; else { LogicEntry::GetInstance()->ProcessPacket(pPacket); if (pPacket->GetPacketType() != SFPACKET_DB) { ReleasePacket(pPacket); } } } }
void SFMulitiCasualGameDispatcher::CasualGameLogicProc(void* Args) { CasualGameParam* pParam = static_cast<CasualGameParam*>(Args); SFIOCPQueue<BasePacket>* pQueue = pParam->pQueue; ILogicEntry* pEntry = pParam->pLogicEntry; while (m_bLogicEnd == false) { BasePacket* pPacket = pQueue->Pop(INFINITE); if (pPacket) { pEntry->ProcessPacket(pPacket); if (pPacket->GetPacketType() != SFPACKET_DB) { ReleasePacket(pPacket); } } } }
BOOL SFTCPNetwork::Update() { while (1) { BasePacket* pPacket = LogicGatewaySingleton::instance()->PopPacket(0); if (pPacket != NULL) { switch (pPacket->GetPacketType()) { case SFPACKET_DATA: m_pTCPCallBack->HandleNetworkMessage(pPacket); m_TCPClient->ReleasePacket(pPacket); break; case SFPACKET_RPC: lfds611_queue_guaranteed_enqueue(m_pQueue, pPacket); break; case SFPACKET_CONNECT: m_pTCPCallBack->HandleConnect(pPacket->GetOwnerSerial()); delete pPacket; break; case SFPACKET_DISCONNECT: m_pTCPCallBack->HandleDisconnect(pPacket->GetOwnerSerial()); delete pPacket; break; } } else { break; } } return TRUE; }
void SFCasualGameDispatcher::LogicThreadProc(void* Args) { UNREFERENCED_PARAMETER(Args); SFEngine* pEngine = SFEngine::GetInstance(); while (m_bLogicEnd == false) { //로직게이트웨이 큐에서 패킷을 꺼낸다. BasePacket* pPacket = LogicGatewaySingleton::instance()->PopPacket(); //로직엔트리 객체의 ProcessPacket 메소드를 호출해서 패킷 처리를 수행한다. LogicEntrySingleton::instance()->ProcessPacket(pPacket); //사용한 패킷을 수거한다. 패킷의 타입에 따라 릴리즈 형태가 다름 switch (pPacket->GetPacketType()) { case SFPACKET_DATA: pEngine->ReleasePacket(pPacket); break; case SFPACKET_CONNECT: case SFPACKET_DISCONNECT: case SFPACKET_TIMER: case SFPACKET_SHOUTER: delete pPacket; break; case SFPACKET_DB: SFDatabase::RecallDBMsg((SFMessage*)pPacket); break; case SFPACKET_SERVERSHUTDOWN: return; default: SFASSERT(0); } } }
void SFMultiLogicDispatcher::PacketDistributorProc(void* Args) { SFMultiLogicDispatcher* pDispatcher = static_cast<SFMultiLogicDispatcher*>(Args); while (true) { BasePacket* pPacket = SFLogicGateway::GetInstance()->PopPacket(); if (pPacket->GetPacketType() == SFPACKET_CONNECT) { pDispatcher->RegisterClient(pPacket); } if (pPacket->GetPacketType() == SFPACKET_TIMER) { for (auto& iter : pDispatcher->m_mapQueue) { #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = iter.second; #else SFLockQueue<BasePacket>* pQueue = iter.second; #endif pQueue->Push(pPacket); //일단 한스레드에만 패킷을 넘기고 전체 로직 스레드에게 타이머 패킷을 보낼 수 있도록 나중에 수정한다 break; } } else if (pPacket->GetPacketType() == SFPACKET_SERVERSHUTDOWN) { for (auto& queue : pDispatcher->m_mapQueue) { BasePacket* pCommand = SFPacketPool::GetInstance()->Alloc(); pCommand->SetSerial(-1); pCommand->SetPacketType(SFPACKET_SERVERSHUTDOWN); #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = queue.second; #else SFLockQueue<BasePacket>* pQueue = queue.second; #endif pQueue->Push(pCommand); } break; } else { ClientInfo* pInfo = pDispatcher->FindClient(pPacket->GetSerial()); if (pInfo != nullptr) { const auto& iter = pDispatcher->m_mapQueue.find(pInfo->channel); if (iter != pDispatcher->m_mapQueue.end()) { #ifdef _WIN32 SFIOCPQueue<BasePacket>* pQueue = iter->second; #else SFLockQueue<BasePacket>* pQueue = iter->second; #endif pQueue->Push(pPacket); } else { LOG(WARNING) << "Invalid Channel Num : " << pInfo->channel; ReleasePacket(pPacket); } } else { LOG(WARNING) << "ClientInfo NULL : " << pPacket->GetSerial(); } } if (pPacket->GetPacketType() == SFPACKET_DISCONNECT) { pDispatcher->UnregisterClient(pPacket); } } }