private void QueueEmptyHandler(LLAgent agent, ThrottleCategoryFlags categories) { if ((categories & ThrottleCategoryFlags.Texture) == ThrottleCategoryFlags.Texture) { ProcessImageQueue(TEXTURE_PACKETS_PER_ROUND); } }
public void FireQueueEmpty(LLAgent agent, ThrottleCategoryFlags categories) { QueueEmptyCallback callback = OnQueueEmpty; if (callback != null) { callback(agent, categories); } }
/// <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); } }
/// <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); }
/// <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); }
public void FireQueueEmpty(LLAgent agent, ThrottleCategoryFlags categories) { m_udp.FireQueueEmpty(agent, categories); }
public void FireQueueEmpty(LLAgent agent, ThrottleCategoryFlags categories) { QueueEmptyCallback callback = OnQueueEmpty; if (callback != null) callback(agent, categories); }
/// <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); } }
public void FireQueueEmpty(LLAgent agent, ThrottleCategoryFlags categories) { m_udp.FireQueueEmpty(agent, categories); }
private void QueueEmptyHandler(LLAgent agent, ThrottleCategoryFlags categories) { if ((categories & ThrottleCategoryFlags.Texture) == ThrottleCategoryFlags.Texture) { ProcessImageQueue(TEXTURE_PACKETS_PER_ROUND); } }
/// <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); }