aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs107
1 files changed, 90 insertions, 17 deletions
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
3582 3582
3583 void HandleQueueEmpty(ThrottleOutPacketType queue) 3583 void HandleQueueEmpty(ThrottleOutPacketType queue)
3584 { 3584 {
3585 int count = 0;
3586
3587 switch (queue) 3585 switch (queue)
3588 { 3586 {
3589 case ThrottleOutPacketType.Texture: 3587 case ThrottleOutPacketType.Texture:
3590 ProcessTextureRequests(); 3588 ProcessTextureRequests();
3591 break; 3589 break;
3592 case ThrottleOutPacketType.Task: 3590 case ThrottleOutPacketType.Task:
3593 lock (m_avatarTerseUpdates.SyncRoot) 3591 if (Monitor.TryEnter(m_avatarTerseUpdates.SyncRoot, 1))
3594 count = m_avatarTerseUpdates.Count;
3595 if (count > 0)
3596 { 3592 {
3597 ProcessAvatarTerseUpdates(); 3593 try
3598 return; 3594 {
3595 if (m_avatarTerseUpdates.Count > 0)
3596 {
3597
3598 ProcessAvatarTerseUpdates();
3599 return;
3600 }
3601 }
3602 finally { Monitor.Exit(m_avatarTerseUpdates.SyncRoot); }
3599 } 3603 }
3600 break; 3604 break;
3601 case ThrottleOutPacketType.State: 3605 case ThrottleOutPacketType.State:
3602 lock (m_primFullUpdates.SyncRoot) 3606 if (Monitor.TryEnter(m_primFullUpdates.SyncRoot, 1))
3603 count = m_primFullUpdates.Count;
3604 if (count > 0)
3605 { 3607 {
3606 ProcessPrimFullUpdates(); 3608 try
3607 return; 3609 {
3610 if (m_primFullUpdates.Count > 0)
3611 {
3612 ProcessPrimFullUpdates();
3613 return;
3614 }
3615 }
3616 finally { Monitor.Exit(m_primFullUpdates.SyncRoot); }
3608 } 3617 }
3609 3618
3610 lock (m_primTerseUpdates.SyncRoot) 3619 if (Monitor.TryEnter(m_primTerseUpdates.SyncRoot, 1))
3611 count = m_primTerseUpdates.Count;
3612 if (count > 0)
3613 { 3620 {
3614 ProcessPrimTerseUpdates(); 3621 try
3615 return; 3622 {
3623 if (m_primTerseUpdates.Count > 0)
3624 {
3625 ProcessPrimTerseUpdates();
3626 return;
3627 }
3628 }
3629 finally { Monitor.Exit(m_primTerseUpdates.SyncRoot); }
3616 } 3630 }
3617 break; 3631 break;
3618 } 3632 }
@@ -3703,6 +3717,37 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3703 } 3717 }
3704 } 3718 }
3705 3719
3720 public void ReprioritizeUpdates(StateUpdateTypes type, UpdatePriorityHandler handler)
3721 {
3722 PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler terse_update_priority_handler =
3723 delegate(ref double priority, uint local_id)
3724 {
3725 priority = handler(new UpdatePriorityData(priority, local_id));
3726 return priority != double.NaN;
3727 };
3728 PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>.UpdatePriorityHandler update_priority_handler =
3729 delegate(ref double priority, uint local_id)
3730 {
3731 priority = handler(new UpdatePriorityData(priority, local_id));
3732 return priority != double.NaN;
3733 };
3734
3735 if ((type & StateUpdateTypes.AvatarTerse) != 0) {
3736 lock (m_avatarTerseUpdates.SyncRoot)
3737 m_avatarTerseUpdates.Reprioritize(terse_update_priority_handler);
3738 }
3739
3740 if ((type & StateUpdateTypes.PrimitiveFull) != 0) {
3741 lock (m_primFullUpdates.SyncRoot)
3742 m_primFullUpdates.Reprioritize(update_priority_handler);
3743 }
3744
3745 if ((type & StateUpdateTypes.PrimitiveTerse) != 0) {
3746 lock (m_primTerseUpdates.SyncRoot)
3747 m_primTerseUpdates.Reprioritize(terse_update_priority_handler);
3748 }
3749 }
3750
3706 public void FlushPrimUpdates() 3751 public void FlushPrimUpdates()
3707 { 3752 {
3708 while (m_primFullUpdates.Count > 0) 3753 while (m_primFullUpdates.Count > 0)
@@ -10465,6 +10510,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10465 #region PriorityQueue 10510 #region PriorityQueue
10466 private class PriorityQueue<TPriority, TValue> 10511 private class PriorityQueue<TPriority, TValue>
10467 { 10512 {
10513 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
10514
10468 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1]; 10515 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1];
10469 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>(); 10516 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>();
10470 private Comparison<TPriority> comparison; 10517 private Comparison<TPriority> comparison;
@@ -10539,6 +10586,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10539 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 10586 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10540 } 10587 }
10541 10588
10589 internal void Reprioritize(UpdatePriorityHandler handler)
10590 {
10591 MinHeapItem item;
10592 TPriority priority;
10593
10594 foreach (LookupItem lookup in new List<LookupItem>(this.lookup_table.Values))
10595 {
10596 if (lookup.Heap.TryGetValue(lookup.Handle, out item))
10597 {
10598 priority = item.Priority;
10599 if (handler(ref priority, item.LocalID))
10600 {
10601 if (lookup.Heap.ContainsHandle(lookup.Handle))
10602 lookup.Heap[lookup.Handle] =
10603 new MinHeapItem(priority, item.Value, item.LocalID);
10604 }
10605 else
10606 {
10607 m_log.Warn("[LLClientView] UpdatePriorityHandle returned false, dropping update");
10608 lookup.Heap.Remove(lookup.Handle);
10609 this.lookup_table.Remove(item.LocalID);
10610 }
10611 }
10612 }
10613 }
10614
10542 #region MinHeapItem 10615 #region MinHeapItem
10543 private struct MinHeapItem : IComparable<MinHeapItem> 10616 private struct MinHeapItem : IComparable<MinHeapItem>
10544 { 10617 {