From ade4bf69b173958fb8b8309760cee9b87cfe2927 Mon Sep 17 00:00:00 2001 From: UbitUmarov Date: Thu, 28 Aug 2014 10:38:31 +0100 Subject: [PATCH] if we send wearables with ThrottleOutPacketType.HighPriority, then we should send other avatarinformation with same priority on same Task category ( plus cleanup ) --- .../ClientStack/Linden/UDP/LLClientView.cs | 111 +----------------- .../ClientStack/Linden/UDP/LLUDPClient.cs | 32 +++-- 2 files changed, 18 insertions(+), 125 deletions(-) diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs index 7087bb79e7..e82f1d77fc 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs @@ -3694,7 +3694,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP // avp.AppearanceData[0].CofVersion = 0; //m_log.DebugFormat("[CLIENT]: Sending appearance for {0} to {1}", agentID.ToString(), AgentId.ToString()); - OutPacket(avp, ThrottleOutPacketType.Task); + OutPacket(avp, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); } public void SendAnimations(UUID[] animations, int[] seqs, UUID sourceAgentId, UUID[] objectIDs) @@ -3722,7 +3722,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP ani.AnimationSourceList[i].ObjectID = objectIDs[i]; } ani.Header.Reliable = false; - OutPacket(ani, ThrottleOutPacketType.Task); + OutPacket(ani, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); } #endregion @@ -3751,7 +3751,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP objupdate.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[1]; objupdate.ObjectData[0] = CreateAvatarUpdateBlock(presence); - OutPacket(objupdate, ThrottleOutPacketType.Task); + OutPacket(objupdate, ThrottleOutPacketType.Task | ThrottleOutPacketType.HighPriority); // We need to record the avatar local id since the root prim of an attachment points to this. // m_attachmentsSent.Add(avatar.LocalId); @@ -3824,65 +3824,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP m_entityUpdates.Enqueue(priority, new EntityUpdate(entity, updateFlags, m_scene.TimeDilation)); } - /* dont use this - udp packet resent must be done at udp level only - re map from a packet to original updates just doesnt work - - /// - /// Requeue an EntityUpdate when it was not acknowledged by the client. - /// We will update the priority and put it in the correct queue, merging update flags - /// with any other updates that may be queued for the same entity. - /// The original update time is used for the merged update. - /// - private void ResendPrimUpdate(EntityUpdate update) - { - // If the update exists in priority queue, it will be updated. - // If it does not exist then it will be added with the current (rather than its original) priority - uint priority = m_prioritizer.GetUpdatePriority(this, update.Entity); - - lock (m_entityUpdates.SyncRoot) - m_entityUpdates.Enqueue(priority, update); - } - - - /// - /// Requeue a list of EntityUpdates when they were not acknowledged by the client. - /// We will update the priority and put it in the correct queue, merging update flags - /// with any other updates that may be queued for the same entity. - /// The original update time is used for the merged update. - /// - private void ResendPrimUpdates(List updates, OutgoingPacket oPacket) - { - // m_log.WarnFormat("[CLIENT] resending prim updates {0}, packet sequence number {1}", updates[0].UpdateTime, oPacket.SequenceNumber); - - // Remove the update packet from the list of packets waiting for acknowledgement - // because we are requeuing the list of updates. They will be resent in new packets - // with the most recent state and priority. - m_udpClient.NeedAcks.Remove(oPacket.SequenceNumber); - - // Count this as a resent packet since we are going to requeue all of the updates contained in it - Interlocked.Increment(ref m_udpClient.PacketsResent); - - // We're not going to worry about interlock yet since its not currently critical that this total count - // is 100% correct - m_udpServer.PacketsResentCount++; - - foreach (EntityUpdate update in updates) - ResendPrimUpdate(update); - } - */ - -// OpenSim.Framework.Lazy> objectUpdateBlocks = new OpenSim.Framework.Lazy>(); -// OpenSim.Framework.Lazy> compressedUpdateBlocks = new OpenSim.Framework.Lazy>(); -// OpenSim.Framework.Lazy> terseUpdateBlocks = new OpenSim.Framework.Lazy>(); -// OpenSim.Framework.Lazy> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy>(); -// -// OpenSim.Framework.Lazy> objectUpdates = new OpenSim.Framework.Lazy>(); -// OpenSim.Framework.Lazy> compressedUpdates = new OpenSim.Framework.Lazy>(); -// OpenSim.Framework.Lazy> terseUpdates = new OpenSim.Framework.Lazy>(); -// OpenSim.Framework.Lazy> terseAgentUpdates = new OpenSim.Framework.Lazy>(); - - private void ProcessEntityUpdates(int maxUpdates) { OpenSim.Framework.Lazy> objectUpdateBlocks = new OpenSim.Framework.Lazy>(); @@ -3895,15 +3836,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP OpenSim.Framework.Lazy> terseUpdates = new OpenSim.Framework.Lazy>(); OpenSim.Framework.Lazy> terseAgentUpdates = new OpenSim.Framework.Lazy>(); -// objectUpdateBlocks.Value.Clear(); -// compressedUpdateBlocks.Value.Clear(); -// terseUpdateBlocks.Value.Clear(); -// terseAgentUpdateBlocks.Value.Clear(); -// objectUpdates.Value.Clear(); -// compressedUpdates.Value.Clear(); -// terseUpdates.Value.Clear(); -// terseAgentUpdates.Value.Clear(); - // Check to see if this is a flush if (maxUpdates <= 0) { @@ -3970,36 +3902,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP if (sp.IsChildAgent) continue; - // If the object is an attachment we don't want it to be in the kill - // record. Else attaching from inworld and subsequently dropping - // it will no longer work. -// lock (m_killRecord) -// { -// m_killRecord.Remove(part.LocalId); -// m_killRecord.Remove(part.ParentGroup.RootPart.LocalId); -// } - } - else - { - // Please do not remove this unless you can demonstrate on the OpenSim mailing list that a client - // will never receive an update after a prim kill. Even then, keeping the kill record may be a good - // safety measure. - // - // If a Linden Lab 1.23.5 client (and possibly later and earlier) receives an object update - // after a kill, it will keep displaying the deleted object until relog. OpenSim currently performs - // updates and kills on different threads with different scheduling strategies, hence this protection. - // - // This doesn't appear to apply to child prims - a client will happily ignore these updates - // after the root prim has been deleted. - // - // We ignore this for attachments because attaching something from inworld breaks unless we do. -// lock (m_killRecord) -// { -// if (m_killRecord.Contains(part.LocalId)) -// continue; -// if (m_killRecord.Contains(part.ParentGroup.RootPart.LocalId)) -// continue; -// } } if (part.ParentGroup.IsAttachment && m_disableFacelights) @@ -4188,16 +4090,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP for (int i = 0; i < blocks.Count; i++) packet.ObjectData[i] = blocks[i]; - -// OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); - // use default udp retry + OutPacket(packet, ThrottleOutPacketType.Task, true); } - - #endregion Packet Sending - } // hack.. dont use diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs index 8852715037..bb68921c29 100644 --- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs @@ -364,9 +364,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP int texture = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); pos += 4; int asset = (int)(BitConverter.ToSingle(adjData, pos) * 0.125f); - int total = resend + land + wind + cloud + task + texture + asset; - total /= 128; - // Make sure none of the throttles are set below our packet MTU, // otherwise a throttle could become permanently clogged resend = Math.Max(resend, LLUDPServer.MTU); @@ -383,8 +380,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP task = task + (int)(m_cannibalrate * texture); texture = (int)((1 - m_cannibalrate) * texture); - total = resend + land + wind + cloud + task + texture + asset; - total /= 128; + // int total = resend + land + wind + cloud + task + texture + asset; + //m_log.DebugFormat("[LLUDPCLIENT]: {0} is setting throttles. Resend={1}, Land={2}, Wind={3}, Cloud={4}, Task={5}, Texture={6}, Asset={7}, Total={8}", // AgentID, resend, land, wind, cloud, task, texture, asset, total); @@ -428,25 +425,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP int i = 0; // multiply by 8 to convert bytes back to bits - rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate * 8 * multiplier; + multiplier *= 8; + + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Resend].RequestedDripRate * multiplier; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; - rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate * 8 * multiplier; + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Land].RequestedDripRate * multiplier; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; - rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate * 8 * multiplier; + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Wind].RequestedDripRate * multiplier; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; - rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate * 8 * multiplier; + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Cloud].RequestedDripRate * multiplier; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; - rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate * 8 * multiplier; + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Task].RequestedDripRate * multiplier; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; - rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate * 8 * multiplier; + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Texture].RequestedDripRate * multiplier; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; - rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate * 8 * multiplier; + rate = (float)m_throttleCategories[(int)ThrottleOutPacketType.Asset].RequestedDripRate * multiplier; Buffer.BlockCopy(Utils.FloatToBytes(rate), 0, data, i, 4); i += 4; m_packedThrottles = data; @@ -485,19 +484,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP TokenBucket bucket = m_throttleCategories[category]; - // Don't send this packet if there is already a packet waiting in the queue - // even if we have the tokens to send it, tokens should go to the already - // queued packets + // Don't send this packet if queue is not empty if (queue.Count > 0 || m_nextPackets[category] != null) { queue.Enqueue(packet, highPriority); return true; } - - + if (!forceQueue && bucket.RemoveTokens(packet.Buffer.DataLength)) { - // Enough tokens were removed from the bucket, the packet will not be queued + // enough tokens so it can be sent imediatly by caller return false; } else