DWORD WINAPI CRcvQueue::worker(LPVOID param) #endif { CRcvQueue* self = (CRcvQueue*)param; sockaddr* addr = (AF_INET == self->m_UnitQueue.m_iIPversion) ? (sockaddr*) new sockaddr_in : (sockaddr*) new sockaddr_in6; CUDT* u = NULL; int32_t id; while (!self->m_bClosing) { #ifdef NO_BUSY_WAITING self->m_pTimer->tick(); #endif // check waiting list, if new socket, insert it to the list while (self->ifNewEntry()) { CUDT* ne = self->getNewEntry(); if (NULL != ne) { self->m_pRcvUList->insert(ne); self->m_pHash->insert(ne->m_SocketID, ne); } } // find next available slot for incoming packet CUnit* unit = self->m_UnitQueue.getNextAvailUnit(); if (NULL == unit) { // no space, skip this packet CPacket temp; temp.m_pcData = new char[self->m_iPayloadSize]; temp.setLength(self->m_iPayloadSize); self->m_pChannel->recvfrom(addr, temp); delete [] temp.m_pcData; goto TIMER_CHECK; } unit->m_Packet.setLength(self->m_iPayloadSize); // reading next incoming packet, recvfrom returns -1 is nothing has been received if (self->m_pChannel->recvfrom(addr, unit->m_Packet) < 0) goto TIMER_CHECK; id = unit->m_Packet.m_iID; // ID 0 is for connection request, which should be passed to the listening socket or rendezvous sockets if (0 == id) { if (NULL != self->m_pListener) self->m_pListener->listen(addr, unit->m_Packet); else if (NULL != (u = self->m_pRendezvousQueue->retrieve(addr, id))) { // asynchronous connect: call connect here // otherwise wait for the UDT socket to retrieve this packet if (!u->m_bSynRecving) u->connect(unit->m_Packet); else self->storePkt(id, unit->m_Packet.clone()); } } else if (id > 0) { if (NULL != (u = self->m_pHash->lookup(id))) { if (CIPAddress::ipcmp(addr, u->m_pPeerAddr, u->m_iIPversion)) { if (u->m_bConnected && !u->m_bBroken && !u->m_bClosing) { if (0 == unit->m_Packet.getFlag()) u->processData(unit); else u->processCtrl(unit->m_Packet); u->checkTimers(); self->m_pRcvUList->update(u); } else{//cout<<"CCBroken"<<endl; } } } else if (NULL != (u = self->m_pRendezvousQueue->retrieve(addr, id))) { if (!u->m_bSynRecving) u->connect(unit->m_Packet); else self->storePkt(id, unit->m_Packet.clone()); } else { //cout<<"CCBroekn"<<endl; } } TIMER_CHECK: // take care of the timing event for all UDT sockets uint64_t currtime; CTimer::rdtsc(currtime); CRNode* ul = self->m_pRcvUList->m_pUList; #ifdef INCAST uint64_t ctime = currtime - 1000 * CTimer::getCPUFrequency(); #else uint64_t ctime = currtime - 10000 * CTimer::getCPUFrequency(); #endif while ((NULL != ul) && (ul->m_llTimeStamp < ctime)) { CUDT* u = ul->m_pUDT; if (u->m_bConnected && !u->m_bBroken && !u->m_bClosing) { u->checkTimers(); self->m_pRcvUList->update(u); } else { // the socket must be removed from Hash table first, then RcvUList self->m_pHash->remove(u->m_SocketID); self->m_pRcvUList->remove(u); u->m_pRNode->m_bOnList = false; } ul = self->m_pRcvUList->m_pUList; } // Check connection requests status for all sockets in the RendezvousQueue. self->m_pRendezvousQueue->updateConnStatus(); } if (AF_INET == self->m_UnitQueue.m_iIPversion) delete (sockaddr_in*)addr; else delete (sockaddr_in6*)addr; #ifndef WIN32 return NULL; #else SetEvent(self->m_ExitCond); return 0; #endif }
DWORD WINAPI CRcvQueue::worker(LPVOID param) #endif { CRcvQueue* self = (CRcvQueue*)param; CUnit temp; temp.m_Packet.m_pcData = new char[self->m_iPayloadSize]; sockaddr* addr = (AF_INET == self->m_UnitQueue.m_iIPversion) ? (sockaddr*) new sockaddr_in : (sockaddr*) new sockaddr_in6; while (!self->m_bClosing) { #ifdef NO_BUSY_WAITING self->m_pTimer->tick(); #endif // check waiting list, if new socket, insert it to the list if (self->ifNewEntry()) { CUDT* ne = self->getNewEntry(); if (NULL != ne) { self->m_pRcvUList->insert(ne); self->m_pHash->insert(ne->m_SocketID, ne); } } // find next available slot for incoming packet CUnit* unit = self->m_UnitQueue.getNextAvailUnit(); if (NULL == unit) unit = &temp; unit->m_Packet.setLength(self->m_iPayloadSize); CUDT* u = NULL; int32_t id; // reading next incoming packet if (self->m_pChannel->recvfrom(addr, unit->m_Packet) <= 0) goto TIMER_CHECK; if (unit == &temp) goto TIMER_CHECK; id = unit->m_Packet.m_iID; // ID 0 is for connection request, which should be passed to the listening socket or rendezvous sockets if (0 == id) { if (NULL != self->m_pListener) ((CUDT*)self->m_pListener)->listen(addr, unit->m_Packet); else if (self->m_pRendezvousQueue->retrieve(addr, id, ((CHandShake*)unit->m_Packet.m_pcData)->m_iID, u)) { if (u->m_bConnected && !u->m_bBroken) u->processCtrl(unit->m_Packet); else self->storePkt(id, unit->m_Packet.clone()); } } else if (id > 0) { if (NULL != (u = self->m_pHash->lookup(id))) { if (u->m_bConnected && !u->m_bBroken) { if (0 == unit->m_Packet.getFlag()) u->processData(unit); else u->processCtrl(unit->m_Packet); u->checkTimers(); self->m_pRcvUList->update(u); } } else self->storePkt(id, unit->m_Packet.clone()); } TIMER_CHECK: // take care of the timing event for all UDT sockets CRNode* ul = self->m_pRcvUList->m_pUList; uint64_t currtime; CTimer::rdtsc(currtime); uint64_t ctime = currtime - 100000 * CTimer::getCPUFrequency(); while ((NULL != ul) && (ul->m_llTimeStamp < ctime)) { CUDT* u = ul->m_pUDT; u->checkTimers(); if (u->m_bConnected && !u->m_bBroken) self->m_pRcvUList->update(u); else { // the socket must be removed from Hash table first, then RcvUList self->m_pHash->remove(u->m_SocketID); self->m_pRcvUList->remove(u); } ul = self->m_pRcvUList->m_pUList; } } delete [] temp.m_Packet.m_pcData; if (AF_INET == self->m_UnitQueue.m_iIPversion) delete (sockaddr_in*)addr; else delete (sockaddr_in6*)addr; return NULL; }