Exemplo n.º 1
0
 private void QueueEmptyHandler(LLAgent agent, ThrottleCategoryFlags categories)
 {
     if ((categories & ThrottleCategoryFlags.Texture) == ThrottleCategoryFlags.Texture)
     {
         ProcessImageQueue(TEXTURE_PACKETS_PER_ROUND);
     }
 }
Exemplo n.º 2
0
        public void FireQueueEmpty(LLAgent agent, ThrottleCategoryFlags categories)
        {
            QueueEmptyCallback callback = OnQueueEmpty;

            if (callback != null)
            {
                callback(agent, categories);
            }
        }
Exemplo n.º 3
0
        /// <summary>
        /// Does an early check to see if this queue empty callback is already
        /// running, then asynchronously firing the event
        /// </summary>
        /// <param name="throttleIndex">Throttle category to fire the callback
        /// for</param>
        private void BeginFireQueueEmpty(ThrottleCategoryFlags categories)
        {
            if (m_nextOnQueueEmpty != 0 && Util.TickCount() >= m_nextOnQueueEmpty)
            {
                // Use a value of 0 to signal that FireQueueEmpty is running
                m_nextOnQueueEmpty = 0;

                // Asynchronously run the callback
                m_server.Scheduler.FireAndForget(FireQueueEmpty, categories);
            }
        }
Exemplo n.º 4
0
        /// <summary>
        /// Processes queued data for this agent and sets the minimum time that
        /// this method can be called again
        /// </summary>
        /// <param name="o">Throttle categories that are empty, stored as an
        /// object to match the WaitCallback delegate signature</param>
        private void FireQueueEmpty(object o)
        {
            const int MIN_CALLBACK_MS     = 30;
            const int EVENTS_PER_CALLBACK = 50;

            ThrottleCategoryFlags categories = (ThrottleCategoryFlags)o;

            int start = Util.TickCount();

            // Dequeue a fixed number of events from the interest list
            m_interestList.DequeueEvents(EVENTS_PER_CALLBACK);

            // Fire the user callback to queue up any other data such as textures
            //FIXME:m_server.FireQueueEmpty(this, categories);

            m_nextOnQueueEmpty = start + MIN_CALLBACK_MS;
            System.Threading.Interlocked.CompareExchange(ref m_nextOnQueueEmpty, 1, 0);
        }
Exemplo n.º 5
0
        /// <summary>
        /// Loops through all of the message queues for this client and tries to send
        /// any outgoing messages, obeying the throttling bucket limits
        /// </summary>
        /// <remarks>This function is only called from a synchronous loop in the
        /// server 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()
        {
            OutgoingMessage message;
            LocklessQueue <OutgoingMessage> queue;
            TokenBucket           bucket;
            bool                  messageSent     = false;
            ThrottleCategoryFlags emptyCategories = 0;

            for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
            {
                bucket = m_throttleCategories[i];

                if (m_nextMessages[i] != null)
                {
                    // This bucket was empty the last time we tried to send a message,
                    // leaving a dequeued message still waiting to be sent out. Try to
                    // send it again
                    OutgoingMessage nextMessage = m_nextMessages[i];
                    if (bucket.RemoveTokens(nextMessage.Data.Length))
                    {
                        // Send the message
                        //FIXME:m_server.SendMessageFinal(nextMessage);
                        m_nextMessages[i] = null;
                        messageSent       = true;
                    }
                }
                else
                {
                    // No dequeued message waiting to be sent, try to pull one off
                    // this queue
                    queue = m_messageOutboxes[i];
                    if (queue.TryDequeue(out message))
                    {
                        // A message was pulled off the queue. See if we have
                        // enough tokens in the bucket to send it out
                        if (bucket.RemoveTokens(message.Data.Length))
                        {
                            // Send the message
                            //FIXME:m_server.SendMessageFinal(message);
                            messageSent = true;
                        }
                        else
                        {
                            // Save the dequeued message for the next iteration
                            m_nextMessages[i] = message;
                        }

                        // 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);
            }

            return(messageSent);
        }
Exemplo n.º 6
0
 public void FireQueueEmpty(LLAgent agent, ThrottleCategoryFlags categories)
 {
     m_udp.FireQueueEmpty(agent, categories);
 }
Exemplo n.º 7
0
 public void FireQueueEmpty(LLAgent agent, ThrottleCategoryFlags categories)
 {
     QueueEmptyCallback callback = OnQueueEmpty;
     if (callback != null)
         callback(agent, categories);
 }
Exemplo n.º 8
0
        /// <summary>
        /// Does an early check to see if this queue empty callback is already
        /// running, then asynchronously firing the event
        /// </summary>
        /// <param name="throttleIndex">Throttle category to fire the callback
        /// for</param>
        private void BeginFireQueueEmpty(ThrottleCategoryFlags categories)
        {
            if (m_nextOnQueueEmpty != 0 && (Environment.TickCount & Int32.MaxValue) >= m_nextOnQueueEmpty)
            {
                // Use a value of 0 to signal that FireQueueEmpty is running
                m_nextOnQueueEmpty = 0;

                // Asynchronously run the callback
                m_server.Scheduler.FireAndForget(FireQueueEmpty, categories);
            }
        }
Exemplo n.º 9
0
 public void FireQueueEmpty(LLAgent agent, ThrottleCategoryFlags categories)
 {
     m_udp.FireQueueEmpty(agent, categories);
 }
Exemplo n.º 10
0
 private void QueueEmptyHandler(LLAgent agent, ThrottleCategoryFlags categories)
 {
     if ((categories & ThrottleCategoryFlags.Texture) == ThrottleCategoryFlags.Texture)
     {
         ProcessImageQueue(TEXTURE_PACKETS_PER_ROUND);
     }
 }
Exemplo n.º 11
0
        /// <summary>
        /// Loops through all of the packet queues for this client and tries to send
        /// any outgoing packets, obeying the throttling bucket limits
        /// </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()
        {
            OutgoingPacket packet;
            LocklessQueue <OutgoingPacket> queue;
            TokenBucket           bucket;
            bool                  packetSent      = false;
            ThrottleCategoryFlags 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.TryDequeue(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);
        }