/// <summary>
        ///     Remove a given number of tokens from the bucket
        /// </summary>
        /// <param name="amount">Number of tokens to remove from the bucket</param>
        /// <param name="dripSucceeded">
        ///     True if tokens were added to the bucket
        ///     during this call, otherwise false
        /// </param>
        /// <returns>
        ///     True if the requested number of tokens were removed from
        ///     the bucket, otherwise false
        /// </returns>
        public bool RemoveTokens(int amount, out bool dripSucceeded)
        {
            if (maxBurst == 0)
            {
                dripSucceeded = true;
                return(true);
            }

            dripSucceeded = Drip();

            if (content - amount >= 0)
            {
                if (parent != null && !parent.RemoveTokens(amount))
                {
                    return(false);
                }

                content -= amount;
                return(true);
            }
            return(false);
        }
Example #2
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.Format(Level.All, AgentID + " - " + packet.Packet.Type);
                    // 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);
        }