着UDT::Startup()的启动,GC线程也随之运行了。
GC主要关注的就是UDTSocket的释放,下面我们来看看这个GC线程是怎么实现的。
2 | void * CUDTUnited::garbageCollect( void * p) |
4 | DWORD WINAPI CUDTUnited::garbageCollect( LPVOID p) |
8 | CUDTUnited* self = (CUDTUnited*)p; |
11 | CGuard gcguard(self->m_GCStopLock); |
14 | while (!self->m_bClosing) |
16 | self->checkBrokenSockets(); |
19 | self->checkTLSValue(); |
28 | gettimeofday(&now, 0); |
29 | timeout.tv_sec = now.tv_sec + 1; |
30 | timeout.tv_nsec = now.tv_usec * 1000; |
32 | pthread_cond_timedwait(&self->m_GCStopCond, &self->m_GCStopLock, &timeout); |
34 | WaitForSingleObject(self->m_GCStopCond, 1000); |
44 | CGuard::enterCS(self->m_ControlLock); |
45 | for (map<UDTSOCKET, CUDTSocket*>::iterator i = self->m_Sockets.begin(); i != self->m_Sockets.end(); ++ i) |
48 | i->second->m_pUDT->m_bBroken = true ; |
49 | i->second->m_pUDT->close(); |
50 | i->second->m_Status = CLOSED; |
51 | i->second->m_TimeStamp = CTimer::getTime(); |
52 | self->m_ClosedSockets[i->first] = i->second; |
56 | map<UDTSOCKET, CUDTSocket*>::iterator ls = self->m_Sockets.find(i->second->m_ListenSocket); |
57 | if (ls == self->m_Sockets.end()) |
60 | ls = self->m_ClosedSockets.find(i->second->m_ListenSocket); |
61 | if (ls == self->m_ClosedSockets.end()) |
67 | CGuard::enterCS(ls->second->m_AcceptLock); |
68 | ls->second->m_pQueuedSockets->erase(i->second->m_SocketID); |
69 | ls->second->m_pAcceptSockets->erase(i->second->m_SocketID); |
70 | CGuard::leaveCS(ls->second->m_AcceptLock); |
73 | self->m_Sockets.clear(); |
76 | for (map<UDTSOCKET, CUDTSocket*>::iterator j = self->m_ClosedSockets.begin(); j != self->m_ClosedSockets.end(); ++ j) |
78 | j->second->m_TimeStamp = 0; |
82 | CGuard::leaveCS(self->m_ControlLock); |
87 | self->checkBrokenSockets(); |
89 | CGuard::enterCS(self->m_ControlLock); |
90 | bool empty = self->m_ClosedSockets.empty(); |
91 | CGuard::leaveCS(self->m_ControlLock); |
1 | void CUDTUnited::checkBrokenSockets() |
3 | CGuard cg(m_ControlLock); |
12 | for (map<UDTSOCKET, CUDTSocket*>::iterator i = m_Sockets.begin(); i != m_Sockets.end(); ++ i) |
16 | if (i->second->m_pUDT->m_bBroken) |
18 | if (i->second->m_Status == LISTENING) |
22 | if (CTimer::getTime() - i->second->m_TimeStamp < 3000000) |
25 | else if ((i->second->m_pUDT->m_pRcvBuffer->getRcvDataSize() > 0) && (i->second->m_pUDT->m_iBrokenCounter -- > 0)) |
36 | i->second->m_Status = CLOSED; |
37 | i->second->m_TimeStamp = CTimer::getTime(); |
38 | tbc.push_back(i->first); |
39 | m_ClosedSockets[i->first] = i->second; |
43 | map<UDTSOCKET, CUDTSocket*>::iterator ls = m_Sockets.find(i->second->m_ListenSocket); |
44 | if (ls == m_Sockets.end()) |
47 | ls = m_ClosedSockets.find(i->second->m_ListenSocket); |
48 | if (ls == m_ClosedSockets.end()) |
54 | CGuard::enterCS(ls->second->m_AcceptLock); |
55 | ls->second->m_pQueuedSockets->erase(i->second->m_SocketID); |
56 | ls->second->m_pAcceptSockets->erase(i->second->m_SocketID); |
57 | CGuard::leaveCS(ls->second->m_AcceptLock); |
62 | for (map<UDTSOCKET, CUDTSocket*>::iterator j = m_ClosedSockets.begin(); j != m_ClosedSockets.end(); ++ j) |
65 | if (j->second->m_pUDT->m_ullLingerExpiration > 0) |
70 | if ((NULL == j->second->m_pUDT->m_pSndBuffer) || (0 == j->second->m_pUDT->m_pSndBuffer->getCurrBufSize()) || (j->second->m_pUDT->m_ullLingerExpiration <= CTimer::getTime())) |
72 | j->second->m_pUDT->m_ullLingerExpiration = 0; |
73 | j->second->m_pUDT->m_bClosing = true ; |
74 | j->second->m_TimeStamp = CTimer::getTime(); |
80 | if ((CTimer::getTime() - j->second->m_TimeStamp > 1000000) && ((NULL == j->second->m_pUDT->m_pRNode) || !j->second->m_pUDT->m_pRNode->m_bOnList)) |
82 | tbr.push_back(j->first); |
89 | for (vector<UDTSOCKET>::iterator k = tbc.begin(); k != tbc.end(); ++ k) |
94 | for (vector<UDTSOCKET>::iterator l = tbr.begin(); l != tbr.end(); ++ l) |
1 | void CUDTUnited::removeSocket( const UDTSOCKET u) |
4 | map<UDTSOCKET, CUDTSocket*>::iterator i = m_ClosedSockets.find(u); |
8 | if (i == m_ClosedSockets.end()) |
13 | const int mid = i->second->m_iMuxID; |
16 | if (NULL != i->second->m_pQueuedSockets) |
18 | CGuard::enterCS(i->second->m_AcceptLock); |
22 | for (set<UDTSOCKET>::iterator q = i->second->m_pQueuedSockets->begin(); q != i->second->m_pQueuedSockets->end(); ++ q) |
24 | m_Sockets[*q]->m_pUDT->m_bBroken = true ; |
25 | m_Sockets[*q]->m_pUDT->close(); |
26 | m_Sockets[*q]->m_TimeStamp = CTimer::getTime(); |
27 | m_Sockets[*q]->m_Status = CLOSED; |
28 | m_ClosedSockets[*q] = m_Sockets[*q]; |
32 | CGuard::leaveCS(i->second->m_AcceptLock); |
38 | map<int64_t, set<UDTSOCKET> >::iterator j = m_PeerRec.find((i->second->m_PeerID << 30) + i->second->m_iISN); |
39 | if (j != m_PeerRec.end()) |
42 | if (j->second.empty()) |
48 | i->second->m_pUDT->close(); |
50 | m_ClosedSockets.erase(i); |
53 | map< int , CMultiplexer>::iterator m; |
54 | m = m_mMultiplexer.find(mid); |
55 | if (m == m_mMultiplexer.end()) |
64 | m->second.m_iRefCount --; |
65 | if (0 == m->second.m_iRefCount) |
67 | m->second.m_pChannel->close(); |
68 | delete m->second.m_pSndQueue; |
69 | delete m->second.m_pRcvQueue; |
70 | delete m->second.m_pTimer; |
71 | delete m->second.m_pChannel; |
72 | m_mMultiplexer.erase(m); |