From fdb2a75ad357668b860fc5055e0630ef75a3ad20 Mon Sep 17 00:00:00 2001 From: John Hurliman Date: Sat, 17 Oct 2009 18:01:22 -0700 Subject: Committing the second part of Jim Greensky @ Intel Lab's patch, re-prioritizing updates --- .../Region/ClientStack/LindenUDP/LLClientView.cs | 107 +++++++++++++++++---- 1 file changed, 90 insertions(+), 17 deletions(-) (limited to 'OpenSim/Region/ClientStack/LindenUDP') diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index 43c3c7c..3b2a604 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs @@ -3582,37 +3582,51 @@ namespace OpenSim.Region.ClientStack.LindenUDP void HandleQueueEmpty(ThrottleOutPacketType queue) { - int count = 0; - switch (queue) { case ThrottleOutPacketType.Texture: ProcessTextureRequests(); break; case ThrottleOutPacketType.Task: - lock (m_avatarTerseUpdates.SyncRoot) - count = m_avatarTerseUpdates.Count; - if (count > 0) + if (Monitor.TryEnter(m_avatarTerseUpdates.SyncRoot, 1)) { - ProcessAvatarTerseUpdates(); - return; + try + { + if (m_avatarTerseUpdates.Count > 0) + { + + ProcessAvatarTerseUpdates(); + return; + } + } + finally { Monitor.Exit(m_avatarTerseUpdates.SyncRoot); } } break; case ThrottleOutPacketType.State: - lock (m_primFullUpdates.SyncRoot) - count = m_primFullUpdates.Count; - if (count > 0) + if (Monitor.TryEnter(m_primFullUpdates.SyncRoot, 1)) { - ProcessPrimFullUpdates(); - return; + try + { + if (m_primFullUpdates.Count > 0) + { + ProcessPrimFullUpdates(); + return; + } + } + finally { Monitor.Exit(m_primFullUpdates.SyncRoot); } } - lock (m_primTerseUpdates.SyncRoot) - count = m_primTerseUpdates.Count; - if (count > 0) + if (Monitor.TryEnter(m_primTerseUpdates.SyncRoot, 1)) { - ProcessPrimTerseUpdates(); - return; + try + { + if (m_primTerseUpdates.Count > 0) + { + ProcessPrimTerseUpdates(); + return; + } + } + finally { Monitor.Exit(m_primTerseUpdates.SyncRoot); } } break; } @@ -3703,6 +3717,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP } } + public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler) + { + PriorityQueue.UpdatePriorityHandler terse_update_priority_handler = + delegate(ref double priority, uint local_id) + { + priority = handler(new UpdatePriorityData(priority, local_id)); + return priority != double.NaN; + }; + PriorityQueue.UpdatePriorityHandler update_priority_handler = + delegate(ref double priority, uint local_id) + { + priority = handler(new UpdatePriorityData(priority, local_id)); + return priority != double.NaN; + }; + + if ((type & StateUpdateTypes.AvatarTerse) != 0) { + lock (m_avatarTerseUpdates.SyncRoot) + m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler); + } + + if ((type & StateUpdateTypes.PrimitiveFull) != 0) { + lock (m_primFullUpdates.SyncRoot) + m_primFullUpdates.Reprioritize(update_priority_handler); + } + + if ((type & StateUpdateTypes.PrimitiveTerse) != 0) { + lock (m_primTerseUpdates.SyncRoot) + m_primTerseUpdates.Reprioritize(terse_update_priority_handler); + } + } + public void FlushPrimUpdates() { while (m_primFullUpdates.Count > 0) @@ -10465,6 +10510,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP #region PriorityQueue private class PriorityQueue { + internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id); + private MinHeap[] heaps = new MinHeap[1]; private Dictionary lookup_table = new Dictionary(); private Comparison comparison; @@ -10539,6 +10586,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); } + internal void Reprioritize(UpdatePriorityHandler handler) + { + MinHeapItem item; + TPriority priority; + + foreach (LookupItem lookup in new List(this.lookup_table.Values)) + { + if (lookup.Heap.TryGetValue(lookup.Handle, out item)) + { + priority = item.Priority; + if (handler(ref priority, item.LocalID)) + { + if (lookup.Heap.ContainsHandle(lookup.Handle)) + lookup.Heap[lookup.Handle] = + new MinHeapItem(priority, item.Value, item.LocalID); + } + else + { + m_log.Warn("[LLClientView] UpdatePriorityHandle returned false, dropping update"); + lookup.Heap.Remove(lookup.Handle); + this.lookup_table.Remove(item.LocalID); + } + } + } + } + #region MinHeapItem private struct MinHeapItem : IComparable { -- cgit v1.1