void CNet::SafeShutdwon(struct iocp_event * pEvent, s32 sdtags) { CConnection * pCConnection = (CConnection *) (pEvent->p); pCConnection->bShutdown = true; CAutoLock(&(pCConnection->sdlock)); pCConnection->nSDTags = pCConnection->nSDTags | sdtags; switch(pCConnection->nSDTags) { case CSD_RECV: shutdown(pEvent->s, SD_RECEIVE); break; case CSD_SEND: shutdown(pEvent->s, SD_SEND); break; case CSD_BOTH: shutdown(pEvent->s, SD_BOTH); break; default: ASSERT(false); return; } if (pCConnection->nSDTags == CSD_BOTH) { pCConnection->stream.clear(); pCConnection->nSDTags = 0; pCConnection->Clear(); m_ConnectPool.Recover(pCConnection); safe_close(pEvent); } closesocket(pCConnection->s); }
s64 CSelectModel::CLoop(const s64 lTick) { s64 lStartTick = ::GetCurrentTimeTick(); CSEvent * pEvent = NULL; while (true) { if (m_Queue[QUENE_TYPE_OUT].read(pEvent)) { ASSERT(pEvent); switch(pEvent->nEventType) { case NET_EVENT_CONNECTED: { ASSERT(m_pFunAddr[CALL_CONNECTED]); pEvent->stream.out(sizeof(RemoteInfo)); s32 nSize = pEvent->stream.size(); if (0 == nSize) { m_pFunAddr[CALL_CONNECTED](pEvent->nConnectID, NULL, 0); } else { m_pFunAddr[CALL_CONNECTED](pEvent->nConnectID, pEvent->stream.buff(), nSize); } } break; case NET_EVENT_CONNECT_FAILED: { ASSERT(m_pFunAddr[CALL_CONNECT_FAILED]); pEvent->stream.out(sizeof(RemoteInfo)); s32 nSize = *(s32 *)(pEvent->stream.buff()); pEvent->stream.out(sizeof(nSize)); if (0 == nSize) { m_pFunAddr[CALL_CONNECT_FAILED](pEvent->nConnectID, NULL, 0); } else { m_pFunAddr[CALL_CONNECT_FAILED](pEvent->nConnectID, pEvent->stream.buff(), nSize); } } break; case NET_EVENT_RECV: { ASSERT(m_pFunAddr[CALL_RECV_DATA]); m_pFunAddr[CALL_RECV_DATA](pEvent->nConnectID, pEvent->stream.buff(), pEvent->stream.size()); } break; case NET_EVENT_CONNECTION_BREAK: { ASSERT(m_pFunAddr[CALL_CONNECTION_BREAK]); CConnection * pConnection = m_ConnectionPool[pEvent->nConnectID]; s32 nSize = pConnection->context.size(); if (0 == nSize) { m_pFunAddr[CALL_CONNECTION_BREAK](pEvent->nConnectID, NULL, 0); } else { m_pFunAddr[CALL_CONNECTION_BREAK](pEvent->nConnectID, pConnection->context.buff(), nSize); } pConnection->Clear(); m_ConnectionPool.Recover(pConnection); } break; default: ASSERT(false); break; } pEvent->stream.clear(); m_EventPool.Recover(pEvent); pEvent = NULL; } else if (m_Queue[QUENE_TYPE_OUT].IsEmpty()){ return ::GetCurrentTimeTick() - lStartTick; } else { s64 lRunTick = ::GetCurrentTimeTick() - lStartTick; if (lRunTick >= lTick) { return lRunTick; } } } }