Example #1
0
        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();
        }