public RemoveTokens ( int amount ) : bool | ||
amount | int | Number of tokens to remove from the bucket |
return | bool |
/// <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); }
/// <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); }