From 6e4d970dae2e292e4155174f5de13f7e774384a3 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Mon, 18 Apr 2011 16:48:49 -0700 Subject: Requeue unacknowledged entity updates rather than resend then "as is". Often, by the time the UDPServer realizes that an entity update packet has not been acknowledged, there is a newer update for the same entity already queued up or there is a higher priority update that should be sent first. This patch eliminates 1:1 packet resends for unacked entity update packets. Insteawd, unacked update packets are decomposed into the original entity updates and those updates are placed back into the priority queues based on their new priority but the original update timestamp. This will generally place them at the head of the line to be put back on the wire as a new outgoing packet but prevents the resend queue from filling up with multiple stale updates for the same entity. This new approach takes advantage of the UDP nature of the Linden protocol in that the intent of a reliable update packet is that if it goes unacknowledge, SOMETHING has to happen to get the update to the client. We are simply making sure that we are resending current object state rather than stale object state. Additionally, this patch includes a generalized callback mechanism so that any caller can specify their own method to call when a packet expires without being acknowledged. We use this mechanism to requeue update packets and otherwise use the UDPServer default method of just putting expired packets in the resend queue. --- OpenSim/Framework/IClientAPI.cs | 59 ++++++++++++++++++++++++++++++++--------- 1 file changed, 47 insertions(+), 12 deletions(-) (limited to 'OpenSim/Framework/IClientAPI.cs') diff --git a/OpenSim/Framework/IClientAPI.cs b/OpenSim/Framework/IClientAPI.cs index f573c32..069987b 100644 --- a/OpenSim/Framework/IClientAPI.cs +++ b/OpenSim/Framework/IClientAPI.cs @@ -572,34 +572,69 @@ namespace OpenSim.Framework public class IEntityUpdate { - public ISceneEntity Entity; - public uint Flags; + private ISceneEntity m_entity; + private uint m_flags; + private int m_updateTime; + + public ISceneEntity Entity + { + get { return m_entity; } + } + + public uint Flags + { + get { return m_flags; } + } + + public int UpdateTime + { + get { return m_updateTime; } + } public virtual void Update(IEntityUpdate update) { - this.Flags |= update.Flags; + m_flags |= update.Flags; + + // Use the older of the updates as the updateTime + if (Util.EnvironmentTickCountCompare(UpdateTime, update.UpdateTime) > 0) + m_updateTime = update.UpdateTime; } public IEntityUpdate(ISceneEntity entity, uint flags) { - Entity = entity; - Flags = flags; + m_entity = entity; + m_flags = flags; + m_updateTime = Util.EnvironmentTickCount(); + } + + public IEntityUpdate(ISceneEntity entity, uint flags, Int32 updateTime) + { + m_entity = entity; + m_flags = flags; + m_updateTime = updateTime; } } - public class EntityUpdate : IEntityUpdate { - // public ISceneEntity Entity; - // public PrimUpdateFlags Flags; - public float TimeDilation; + private float m_timeDilation; + + public float TimeDilation + { + get { return m_timeDilation; } + } public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation) - : base(entity,(uint)flags) + : base(entity, (uint)flags) { - //Entity = entity; // Flags = flags; - TimeDilation = timedilation; + m_timeDilation = timedilation; + } + + public EntityUpdate(ISceneEntity entity, PrimUpdateFlags flags, float timedilation, Int32 updateTime) + : base(entity,(uint)flags,updateTime) + { + m_timeDilation = timedilation; } } -- cgit v1.1