public void insert(UDT u) { RNode n = u.m_pRNode; n.m_llTimeStamp = Timer.rdtsc(); // always insert at the end for RcvUList m_nodeList.Add(n); }
public void remove(UDT u) { RNode n = u.m_pRNode; if (!n.m_bOnList) { return; } m_nodeList.Remove(n); }
public void update(UDT u) { RNode n = u.m_pRNode; if (!n.m_bOnList) { return; } RNode match = m_nodeList.Find(x => x.Equals(n)); if (match.Equals(default(RNode))) { return; } match.m_llTimeStamp = Timer.rdtsc(); }
static void worker(object param) { RcvQueue self = param as RcvQueue; if (self == null) { return; } IPEndPoint addr = new IPEndPoint(IPAddress.Any, 0); UDT u = null; int id; while (!self.m_bClosing) { self.m_pTimer.tick(); // check waiting list, if new socket, insert it to the list while (self.ifNewEntry()) { UDT ne = self.getNewEntry(); if (null != ne) { self.m_pRcvUList.insert(ne); self.m_hash.Add(ne.m_SocketID, ne); } } // find next available slot for incoming packet Unit unit = new Unit(); unit.m_Packet.setLength(self.m_iPayloadSize); // reading next incoming packet, recvfrom returns -1 is nothing has been received if (self.m_pChannel.recvfrom(ref addr, unit.m_Packet) < 0) { goto TIMER_CHECK; } id = unit.m_Packet.GetId(); // 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, ref 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 { Packet newPacket = new Packet(); newPacket.Clone(unit.m_Packet); self.storePkt(id, newPacket); } } } else if (id > 0) { if (self.m_hash.TryGetValue(id, out u)) { if (addr.Equals(u.m_pPeerAddr)) { 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 if (null != (u = self.m_pRendezvousQueue.retrieve(addr, ref id))) { if (!u.m_bSynRecving) { u.connect(unit.m_Packet); } else { Packet newPacket = new Packet(); newPacket.Clone(unit.m_Packet); self.storePkt(id, newPacket); } } } TIMER_CHECK: // take care of the timing event for all UDT sockets ulong currtime = Timer.rdtsc(); ulong ctime = currtime - 100000 * Timer.getCPUFrequency(); for (int i = 0; i < self.m_pRcvUList.m_nodeList.Count; ++i) { RNode ul = self.m_pRcvUList.m_nodeList[0]; if (ul.m_llTimeStamp >= ctime) { break; } 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_hash.Remove(u.m_SocketID); self.m_pRcvUList.remove(u); u.m_pRNode.m_bOnList = false; } } // Check connection requests status for all sockets in the RendezvousQueue. self.m_pRendezvousQueue.updateConnStatus(); } self.m_ExitCond.Set(); }