SendPacketFinal() 개인적인 메소드

Actually send a packet to a client.
private SendPacketFinal ( OutgoingPacket outgoingPacket ) : void
outgoingPacket OutgoingPacket
리턴 void
예제 #1
0
        /// <summary>
        /// Loops through all of the packet queues for this client and tries to send
        /// an outgoing packet from each, obeying the throttling bucket limits
        /// </summary>
        ///
        /// <remarks>
        /// Packet queues are inspected in ascending numerical order starting from 0.  Therefore, queues with a lower
        /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have
        /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the
        /// wind queue).
        ///
        /// This function is only called from a synchronous loop in the
        /// UDPServer so we don't need to bother making this thread safe
        /// </remarks>
        ///
        /// <returns>True if any packets were sent, otherwise false</returns>
        public bool DequeueOutgoing()
        {
            OutgoingPacket packet;

            OpenSim.Framework.LocklessQueue <OutgoingPacket> queue;
            TokenBucket bucket;
            bool        packetSent = false;
            ThrottleOutPacketTypeFlags emptyCategories = 0;

            //string queueDebugOutput = String.Empty; // Serious debug business

            for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
            {
                bucket = m_throttleCategories[i];
                //queueDebugOutput += m_packetOutboxes[i].Count + " ";  // Serious debug business

                if (m_nextPackets[i] != null)
                {
                    // This bucket was empty the last time we tried to send a packet,
                    // leaving a dequeued packet still waiting to be sent out. Try to
                    // send it again
                    OutgoingPacket nextPacket = m_nextPackets[i];
                    if (bucket.RemoveTokens(nextPacket.Buffer.DataLength))
                    {
                        // Send the packet
                        m_udpServer.SendPacketFinal(nextPacket);
                        m_nextPackets[i] = null;
                        packetSent       = true;
                    }
                }
                else
                {
                    // No dequeued packet waiting to be sent, try to pull one off
                    // this queue
                    queue = m_packetOutboxes[i];
                    if (queue.Dequeue(out packet))
                    {
                        // A packet was pulled off the queue. See if we have
                        // enough tokens in the bucket to send it out
                        if (bucket.RemoveTokens(packet.Buffer.DataLength))
                        {
                            // Send the packet
                            m_udpServer.SendPacketFinal(packet);
                            packetSent = true;
                        }
                        else
                        {
                            // Save the dequeued packet for the next iteration
                            m_nextPackets[i] = packet;
                        }

                        // If the queue is empty after this dequeue, fire the queue
                        // empty callback now so it has a chance to fill before we
                        // get back here
                        if (queue.Count == 0)
                        {
                            emptyCategories |= CategoryToFlag(i);
                        }
                    }
                    else
                    {
                        // No packets in this queue. Fire the queue empty callback
                        // if it has not been called recently
                        emptyCategories |= CategoryToFlag(i);
                    }
                }
            }

            if (emptyCategories != 0)
            {
                BeginFireQueueEmpty(emptyCategories);
            }

            //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business
            return(packetSent);
        }
예제 #2
0
        /// <summary>
        /// Loops through all of the packet queues for this client and tries to send
        /// an outgoing packet from each, obeying the throttling bucket limits
        /// </summary>
        /// 
        /// Packet queues are inspected in ascending numerical order starting from 0.  Therefore, queues with a lower 
        /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have
        /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the
        /// wind queue).
        /// 
        /// <remarks>This function is only called from a synchronous loop in the
        /// UDPServer so we don't need to bother making this thread safe</remarks>
        /// <returns>True if any packets were sent, otherwise false</returns>
        public bool DequeueOutgoing (int MaxNPacks)
        {
            OutgoingPacket packet;
            bool packetSent = false;
            ThrottleOutPacketTypeFlags emptyCategories = 0;

            if (m_nextOutPackets != null)
            {
                OutgoingPacket nextPacket = m_nextOutPackets;
                if (m_throttle.RemoveTokens (nextPacket.Buffer.DataLength))
                {
                    // Send the packet
                    m_udpServer.SendPacketFinal (nextPacket);
                    m_nextOutPackets = null;
                    packetSent = true;
                    this.PacketsSent++;
                }
            }
            else
            {
                // No dequeued packet waiting to be sent, try to pull one off
                // this queue
                if (m_outbox.Dequeue (out packet))
                {
                    // A packet was pulled off the queue. See if we have
                    // enough tokens in the bucket to send it out
                    if (packet.Category == ThrottleOutPacketType.OutBand || m_throttle.RemoveTokens (packet.Buffer.DataLength))
                    {
                        // Send the packet
                        m_udpServer.SendPacketFinal (packet);
                        packetSent = true;

                        if (m_throttle.MaxBurst < TotalRateRequested)
                        {
                            float tmp = (float)m_throttle.MaxBurst * 1.005f;
                            m_throttle.DripRate = (int)tmp;
                            m_throttle.MaxBurst = (int)tmp;
                        }

                        this.PacketsSent++;
                    }
                    else
                    {
                        m_nextOutPackets = packet;
                    }
                }
                else
                {
                    emptyCategories = (ThrottleOutPacketTypeFlags)0xffff;
                }
            }

            if (m_outbox.count < 100)
            {
                emptyCategories = (ThrottleOutPacketTypeFlags)0xffff;
                BeginFireQueueEmpty (emptyCategories);
            }
            /*
                        if (emptyCategories != 0)
                            BeginFireQueueEmpty(emptyCategories);
                        else
                            {
                            int i = MapCatsToPriority[(int)ThrottleOutPacketType.Texture]; // hack to keep textures flowing for now
                            if (m_outbox.queues[i].Count < 30)
                                {
                                emptyCategories |= ThrottleOutPacketTypeFlags.Texture;
                                }
                            }
            */

            //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business
            return packetSent;
            /*
  
                         OutgoingPacket packet;
                        OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
                        TokenBucket bucket;
                        bool packetSent = false;
                        ThrottleOutPacketTypeFlags emptyCategories = 0;

                        //string queueDebugOutput = String.Empty; // Serious debug business
                        int npacksTosent = MaxNPacks;

                        int i = m_lastthrottleCategoryChecked;
                        for (int j = 0; j < (int)ThrottleOutPacketType.OutBand; j++) // don't check OutBand
                        {

                            bucket = m_throttleCategories[i];
                            //queueDebugOutput += m_packetOutboxes[i].Count + " ";  // Serious debug business

                            if (m_nextPackets[i] != null)
                            {
                                // This bucket was empty the last time we tried to send a packet,
                                // leaving a dequeued packet still waiting to be sent out. Try to
                                // send it again
                                OutgoingPacket nextPacket = m_nextPackets[i];
                                if (bucket.RemoveTokens(nextPacket.Buffer.DataLength))
                                {
                                    // Send the packet
                                    m_udpServer.SendPacketFinal(nextPacket);
                                    m_nextPackets[i] = null;
                                    packetSent = true;
                                    this.PacketsSent++;
                                }
                            }
                            else
                            {
                                // No dequeued packet waiting to be sent, try to pull one off
                                // this queue
                                queue = m_packetOutboxes[i];
                                if (queue.Dequeue(out packet))
                                {
                                    // A packet was pulled off the queue. See if we have
                                    // enough tokens in the bucket to send it out
                                    if (bucket.RemoveTokens(packet.Buffer.DataLength))
                                    {
                                        // Send the packet
                                        m_udpServer.SendPacketFinal(packet);
                                        packetSent = true;
                                        this.PacketsSent++;
                                    }
                                    else
                                    {
                                        // Save the dequeued packet for the next iteration
                                        m_nextPackets[i] = packet;
                                    }

                                    // If the queue is empty after this dequeue, fire the queue
                                    // empty callback now so it has a chance to fill before we 
                                    // get back here
                                    if (queue.Count == 0)
                                        emptyCategories |= CategoryToFlag(i);
                                }
                                else
                                {
                                    // No packets in this queue. Fire the queue empty callback
                                    // if it has not been called recently
                                    emptyCategories |= CategoryToFlag(i);
                                }
                            }

                            if (++i >= (int)ThrottleOutPacketType.OutBand)
                                i = 0;

                            if (--npacksTosent <= 0)
                                break;
                        }

                        m_lastthrottleCategoryChecked = i;

                        // send at least one outband packet 

                        if (npacksTosent <= 0)
                            npacksTosent = 1;

                        i = (int)ThrottleOutPacketType.OutBand;

                        while (npacksTosent > 0)
                        {
                            //outband has no tokens checking and no throttle
                            // No dequeued packet waiting to be sent, try to pull one off
                            // this queue
                            queue = m_packetOutboxes[i];
                            if (queue.Dequeue(out packet))
                            {
                                // A packet was pulled off the queue. See if we have
                                // enough tokens in the bucket to send it out

                                //                        if (bucket.RemoveTokens(packet.Buffer.DataLength))
                                //                            {
                                // Send the packet
                                m_udpServer.SendPacketFinal(packet);
                                packetSent = true;
                                this.PacketsSent++;
                                //                            }
            //                                            else
            //                                                {
                                                            // Save the dequeued packet for the next iteration
            //                                                m_nextPackets[i] = packet;
            //                                                }

                                // If the queue is empty after this dequeue, fire the queue
                                // empty callback now so it has a chance to fill before we 
                                // get back here
                                if (queue.Count == 0)
                                    emptyCategories |= CategoryToFlag(i);
                            }
                            else
                            {
                                // No packets in this queue. Fire the queue empty callback
                                // if it has not been called recently
                                emptyCategories |= CategoryToFlag(i);
                                break;
                            }
                            npacksTosent--;
                        }

                        if (emptyCategories != 0)
                            BeginFireQueueEmpty(emptyCategories);

                        //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business
                        return packetSent;
             */

        }
예제 #3
0
        /// <summary>
        /// Loops through all of the packet queues for this client and tries to send
        /// an outgoing packet from each, obeying the throttling bucket limits
        /// </summary>
        ///
        /// <remarks>
        /// Packet queues are inspected in ascending numerical order starting from 0.  Therefore, queues with a lower
        /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have
        /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the
        /// wind queue).
        ///
        /// This function is only called from a synchronous loop in the
        /// UDPServer so we don't need to bother making this thread safe
        /// </remarks>
        ///
        /// <returns>True if any packets were sent, otherwise false</returns>
        public bool DequeueOutgoing()
        {
//            if (m_deliverPackets == false) return false;

            OutgoingPacket packet = null;
            DoubleLocklessQueue <OutgoingPacket> queue;
            bool packetSent = false;
            ThrottleOutPacketTypeFlags emptyCategories = 0;

            //string queueDebugOutput = String.Empty; // Serious debug business
            // do resends

            packet = m_nextPackets[0];
            if (packet != null)
            {
                if (packet.Buffer != null)
                {
                    if (m_throttleCategories[0].RemoveTokens(packet.Buffer.DataLength))
                    {
                        // Send the packet
                        m_udpServer.SendPacketFinal(packet);
                        packetSent       = true;
                        m_nextPackets[0] = null;
                    }
                }
                else
                {
                    m_nextPackets[0] = null;
                }
            }
            else
            {
                queue = m_packetOutboxes[0];
                if (queue != null)
                {
                    if (queue.Dequeue(out packet))
                    {
                        // A packet was pulled off the queue. See if we have
                        // enough tokens in the bucket to send it out
                        if (packet.Buffer != null)
                        {
                            if (m_throttleCategories[0].RemoveTokens(packet.Buffer.DataLength))
                            {
                                // Send the packet
                                m_udpServer.SendPacketFinal(packet);
                                packetSent = true;
                            }
                            else
                            {
                                // Save the dequeued packet for the next iteration
                                m_nextPackets[0] = packet;
                            }
                        }
                    }
                }
                else
                {
                    m_packetOutboxes[0] = new DoubleLocklessQueue <OutgoingPacket>();
                }
            }

            if (NeedAcks.Count() > 50)
            {
                Interlocked.Increment(ref AckStalls);
                return(true);
            }

            for (int i = 1; i < THROTTLE_CATEGORY_COUNT; i++)
            {
                //queueDebugOutput += m_packetOutboxes[i].Count + " ";  // Serious debug business

                packet = m_nextPackets[i];
                if (packet != null)
                {
                    if (packet.Buffer == null)
                    {
                        if (m_packetOutboxes[i].Count < 5)
                        {
                            emptyCategories |= CategoryToFlag(i);
                        }
                        m_nextPackets[i] = null;
                        continue;
                    }

                    if (m_throttleCategories[i].RemoveTokens(packet.Buffer.DataLength))
                    {
                        // Send the packet
                        m_udpServer.SendPacketFinal(packet);
                        m_nextPackets[i] = null;
                        packetSent       = true;

                        if (m_packetOutboxes[i].Count < 5)
                        {
                            emptyCategories |= CategoryToFlag(i);
                        }
                    }
                }
                else
                {
                    // No dequeued packet waiting to be sent, try to pull one off
                    // this queue
                    queue = m_packetOutboxes[i];
                    if (queue.Dequeue(out packet))
                    {
                        if (packet.Buffer == null)
                        {
                            // packet canceled elsewhere (by a ack for example)
                            if (queue.Count < 5)
                            {
                                emptyCategories |= CategoryToFlag(i);
                            }
                            continue;
                        }

                        if (m_throttleCategories[i].RemoveTokens(packet.Buffer.DataLength))
                        {
                            // Send the packet
                            m_udpServer.SendPacketFinal(packet);
                            packetSent = true;
                            if (queue.Count < 5)
                            {
                                emptyCategories |= CategoryToFlag(i);
                            }
                        }
                        else
                        {
                            // Save the dequeued packet for the next iteration
                            m_nextPackets[i] = packet;
                        }
                    }
                    else
                    {
                        // No packets in this queue. Fire the queue empty callback
                        // if it has not been called recently
                        emptyCategories |= CategoryToFlag(i);
                    }
                }
            }

            if (emptyCategories != 0)
            {
                BeginFireQueueEmpty(emptyCategories);
            }

            //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business
            return(packetSent);
        }
예제 #4
0
        /// <summary>
        /// Loops through all of the packet queues for this client and tries to send
        /// an outgoing packet from each, obeying the throttling bucket limits
        /// </summary>
        ///
        /// Packet queues are inspected in ascending numerical order starting from 0.  Therefore, queues with a lower
        /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have
        /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the
        /// wind queue).
        ///
        /// <remarks>This function is only called from a synchronous loop in the
        /// UDPServer so we don't need to bother making this thread safe</remarks>
        /// <returns>True if any packets were sent, otherwise false</returns>
        public bool DequeueOutgoing(int MaxNPacks)
        {
            OutgoingPacket packet;
            bool           packetSent = false;

            for (int i = 0; i < MaxNPacks; i++)
            {
                if (m_nextOutPackets != null)
                {
                    OutgoingPacket nextPacket = m_nextOutPackets;
                    if (m_throttle.RemoveTokens(nextPacket.Buffer.DataLength))
                    {
                        // Send the packet
                        m_udpServer.SendPacketFinal(nextPacket);
                        m_nextOutPackets = null;
                        packetSent       = true;
                        this.PacketsSent++;
                    }
                    else
                    {
                        int prio = MapCatsToPriority[(int)nextPacket.Category];
                        prio++;
                        if (prio > MapCatsToPriority.Length)
                        {
                            prio--;
                        }
                        m_outbox.Enqueue(prio, nextPacket);
                        m_nextOutPackets = null;
                    }
                }
                else
                {
                    // No dequeued packet waiting to be sent, try to pull one off
                    // this queue
                    if (m_outbox.Dequeue(out packet))
                    {
                        // A packet was pulled off the queue. See if we have
                        // enough tokens in the bucket to send it out
                        if (packet.Category == ThrottleOutPacketType.OutBand || m_throttle.RemoveTokens(packet.Buffer.DataLength))
                        {
                            // Send the packet
                            m_udpServer.SendPacketFinal(packet);
                            packetSent = true;

                            if (m_throttle.MaxBurst < TotalRateRequested)
                            {
                                float tmp = (float)m_throttle.MaxBurst * 1.005f;
                                m_throttle.DripRate = (int)tmp;
                                m_throttle.MaxBurst = (int)tmp;
                            }

                            this.PacketsSent++;
                        }
                        else
                        {
                            m_nextOutPackets = packet;
                        }
                    }
                    else
                    {
                        break;
                    }
                }
            }

            if (m_outbox.count < 100 || m_lastEmptyUpdates > 10)
            {
                //if(m_outbox.count > 100)
                //    MainConsole.Instance.Output(m_outbox.count.ToString(), log4net.Core.Level.Alert);
                m_lastEmptyUpdates = 0;
                BeginFireQueueEmpty();
            }
            else
            {
                m_lastEmptyUpdates++;
            }

            //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business
            return(packetSent);

            /*
             *
             *           OutgoingPacket packet;
             *          OpenSim.Framework.LocklessQueue<OutgoingPacket> queue;
             *          TokenBucket bucket;
             *          bool packetSent = false;
             *          ThrottleOutPacketTypeFlags emptyCategories = 0;
             *
             *          //string queueDebugOutput = String.Empty; // Serious debug business
             *          int npacksTosent = MaxNPacks;
             *
             *          int i = m_lastthrottleCategoryChecked;
             *          for (int j = 0; j < (int)ThrottleOutPacketType.OutBand; j++) // don't check OutBand
             *          {
             *
             *              bucket = m_throttleCategories[i];
             *              //queueDebugOutput += m_packetOutboxes[i].Count + " ";  // Serious debug business
             *
             *              if (m_nextPackets[i] != null)
             *              {
             *                  // This bucket was empty the last time we tried to send a packet,
             *                  // leaving a dequeued packet still waiting to be sent out. Try to
             *                  // send it again
             *                  OutgoingPacket nextPacket = m_nextPackets[i];
             *                  if (bucket.RemoveTokens(nextPacket.Buffer.DataLength))
             *                  {
             *                      // Send the packet
             *                      m_udpServer.SendPacketFinal(nextPacket);
             *                      m_nextPackets[i] = null;
             *                      packetSent = true;
             *                      this.PacketsSent++;
             *                  }
             *              }
             *              else
             *              {
             *                  // No dequeued packet waiting to be sent, try to pull one off
             *                  // this queue
             *                  queue = m_packetOutboxes[i];
             *                  if (queue.Dequeue(out packet))
             *                  {
             *                      // A packet was pulled off the queue. See if we have
             *                      // enough tokens in the bucket to send it out
             *                      if (bucket.RemoveTokens(packet.Buffer.DataLength))
             *                      {
             *                          // Send the packet
             *                          m_udpServer.SendPacketFinal(packet);
             *                          packetSent = true;
             *                          this.PacketsSent++;
             *                      }
             *                      else
             *                      {
             *                          // Save the dequeued packet for the next iteration
             *                          m_nextPackets[i] = packet;
             *                      }
             *
             *                      // If the queue is empty after this dequeue, fire the queue
             *                      // empty callback now so it has a chance to fill before we
             *                      // get back here
             *                      if (queue.Count == 0)
             *                          emptyCategories |= CategoryToFlag(i);
             *                  }
             *                  else
             *                  {
             *                      // No packets in this queue. Fire the queue empty callback
             *                      // if it has not been called recently
             *                      emptyCategories |= CategoryToFlag(i);
             *                  }
             *              }
             *
             *              if (++i >= (int)ThrottleOutPacketType.OutBand)
             *                  i = 0;
             *
             *              if (--npacksTosent <= 0)
             *                  break;
             *          }
             *
             *          m_lastthrottleCategoryChecked = i;
             *
             *          // send at least one outband packet
             *
             *          if (npacksTosent <= 0)
             *              npacksTosent = 1;
             *
             *          i = (int)ThrottleOutPacketType.OutBand;
             *
             *          while (npacksTosent > 0)
             *          {
             *              //outband has no tokens checking and no throttle
             *              // No dequeued packet waiting to be sent, try to pull one off
             *              // this queue
             *              queue = m_packetOutboxes[i];
             *              if (queue.Dequeue(out packet))
             *              {
             *                  // A packet was pulled off the queue. See if we have
             *                  // enough tokens in the bucket to send it out
             *
             *                  //                        if (bucket.RemoveTokens(packet.Buffer.DataLength))
             *                  //                            {
             *                  // Send the packet
             *                  m_udpServer.SendPacketFinal(packet);
             *                  packetSent = true;
             *                  this.PacketsSent++;
             *                  //                            }
             * //                                            else
             * //                                                {
             *                                              // Save the dequeued packet for the next iteration
             * //                                                m_nextPackets[i] = packet;
             * //                                                }
             *
             *                  // If the queue is empty after this dequeue, fire the queue
             *                  // empty callback now so it has a chance to fill before we
             *                  // get back here
             *                  if (queue.Count == 0)
             *                      emptyCategories |= CategoryToFlag(i);
             *              }
             *              else
             *              {
             *                  // No packets in this queue. Fire the queue empty callback
             *                  // if it has not been called recently
             *                  emptyCategories |= CategoryToFlag(i);
             *                  break;
             *              }
             *              npacksTosent--;
             *          }
             *
             *          if (emptyCategories != 0)
             *              BeginFireQueueEmpty(emptyCategories);
             *
             *          //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business
             *          return packetSent;
             */
        }
예제 #5
0
        /// <summary>
        /// Loops through all of the packet queues for this client and tries to send
        /// an outgoing packet from each, obeying the throttling bucket limits
        /// </summary>
        ///
        /// <remarks>
        /// Packet queues are inspected in ascending numerical order starting from 0.  Therefore, queues with a lower
        /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have
        /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the
        /// wind queue).
        ///
        /// This function is only called from a synchronous loop in the
        /// UDPServer so we don't need to bother making this thread safe
        /// </remarks>
        ///
        /// <returns>True if any packets were sent, otherwise false</returns>
        public bool DequeueOutgoing()
        {
//            if (m_deliverPackets == false) return false;

            OutgoingPacket packet = null;
            DoubleLocklessQueue <OutgoingPacket> queue;
            TokenBucket bucket;
            bool        packetSent = false;
            ThrottleOutPacketTypeFlags emptyCategories = 0;

            //string queueDebugOutput = String.Empty; // Serious debug business

            for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
            {
                bucket = m_throttleCategories[i];
                //queueDebugOutput += m_packetOutboxes[i].Count + " ";  // Serious debug business

                if (m_nextPackets[i] != null)
                {
                    // This bucket was empty the last time we tried to send a packet,
                    // leaving a dequeued packet still waiting to be sent out. Try to
                    // send it again
                    OutgoingPacket nextPacket = m_nextPackets[i];
                    if (nextPacket.Buffer == null)
                    {
                        if (m_packetOutboxes[i].Count < 5)
                        {
                            emptyCategories |= CategoryToFlag(i);
                        }
                        continue;
                    }
                    if (bucket.RemoveTokens(nextPacket.Buffer.DataLength))
                    {
                        // Send the packet
                        m_udpServer.SendPacketFinal(nextPacket);
                        m_nextPackets[i] = null;
                        packetSent       = true;

                        if (m_packetOutboxes[i].Count < 5)
                        {
                            emptyCategories |= CategoryToFlag(i);
                        }
                    }
                }
                else
                {
                    // No dequeued packet waiting to be sent, try to pull one off
                    // this queue
                    queue = m_packetOutboxes[i];
                    if (queue != null)
                    {
                        bool success = false;
                        try
                        {
                            success = queue.Dequeue(out packet);
                        }
                        catch
                        {
                            m_packetOutboxes[i] = new DoubleLocklessQueue <OutgoingPacket>();
                        }
                        if (success)
                        {
                            // A packet was pulled off the queue. See if we have
                            // enough tokens in the bucket to send it out
                            if (packet.Buffer == null)
                            {
                                // packet canceled elsewhere (by a ack for example)
                                if (queue.Count < 5)
                                {
                                    emptyCategories |= CategoryToFlag(i);
                                }
                            }
                            else
                            {
                                if (bucket.RemoveTokens(packet.Buffer.DataLength))
                                {
                                    // Send the packet
                                    m_udpServer.SendPacketFinal(packet);
                                    packetSent = true;

                                    if (queue.Count < 5)
                                    {
                                        emptyCategories |= CategoryToFlag(i);
                                    }
                                }
                                else
                                {
                                    // Save the dequeued packet for the next iteration
                                    m_nextPackets[i] = packet;
                                }
                            }
                        }
                        else
                        {
                            // No packets in this queue. Fire the queue empty callback
                            // if it has not been called recently
                            emptyCategories |= CategoryToFlag(i);
                        }
                    }
                    else
                    {
                        m_packetOutboxes[i] = new DoubleLocklessQueue <OutgoingPacket>();
                        emptyCategories    |= CategoryToFlag(i);
                    }
                }
            }

            if (emptyCategories != 0)
            {
                BeginFireQueueEmpty(emptyCategories);
            }

            //m_log.Info("[LLUDPCLIENT]: Queues: " + queueDebugOutput); // Serious debug business
            return(packetSent);
        }
예제 #6
0
        /// <summary>
        ///   tries to send queued packets
        /// </summary>
        /// <remarks>
        ///   This function is only called from a synchronous loop in the
        ///   UDPServer so we don't need to bother making this thread safe
        /// </remarks>
        /// <returns>True if any packets were sent, otherwise false</returns>
        public bool DequeueOutgoing(int MaxNPacks)
        {
            bool packetSent = false;

            for (int i = 0; i < MaxNPacks; i++)
            {
                OutgoingPacket packet;
                if (m_nextOutPacket != null)
                {
                    packet = m_nextOutPacket;
                    if (m_throttle.RemoveTokens(packet.Buffer.DataLength))
                    {
                        // Send the packet
                        m_udpServer.SendPacketFinal(packet);
                        m_nextOutPacket = null;
                        packetSent      = true;
                    }
                }
                // No dequeued packet waiting to be sent, try to pull one off
                // this queue
                else if (m_outbox.Dequeue(out packet))
                {
                    MainConsole.Instance.Output(AgentID + " - " + packet.Packet.Type, "Verbose");
                    // A packet was pulled off the queue. See if we have
                    // enough tokens in the bucket to send it out
                    if (packet.Category == ThrottleOutPacketType.OutBand ||
                        m_throttle.RemoveTokens(packet.Buffer.DataLength))
                    {
                        packetSent = true;
                        //Send the packet
                        PacketsCounts[(int)packet.Category] += packet.Packet.Length;
                        m_udpServer.SendPacketFinal(packet);
                        PacketsSent++;
                    }
                    else
                    {
                        m_nextOutPacket = packet;
                        break;
                    }
                }
                else
                {
                    break;
                }
            }

            if (packetSent)
            {
                if (m_throttle.MaxBurst < TotalRateRequested)
                {
                    float tmp = m_throttle.MaxBurst * 1.005f;
                    m_throttle.DripRate = (int)tmp;
                    m_throttle.MaxBurst = (int)tmp;
                }
            }


            if (m_nextOnQueueEmpty != 0 && Util.EnvironmentTickCountSubtract(m_nextOnQueueEmpty) >= 0)
            {
                // Use a value of 0 to signal that FireQueueEmpty is running
                m_nextOnQueueEmpty = 0;
                // Asynchronously run the callback
                int   ptmp = m_outbox.queues[MapCatsToPriority[(int)ThrottleOutPacketType.Task]].Count;
                int   atmp = m_outbox.queues[MapCatsToPriority[(int)ThrottleOutPacketType.AvatarInfo]].Count;
                int   ttmp = m_outbox.queues[MapCatsToPriority[(int)ThrottleOutPacketType.Texture]].Count;
                int[] arg  = { ptmp, atmp, ttmp };
                Util.FireAndForget(FireQueueEmpty, arg);
            }

            return(packetSent);
        }