aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorJohn Hurliman2009-10-19 15:19:09 -0700
committerJohn Hurliman2009-10-19 15:19:09 -0700
commit142008121e2e9c5ca5fca5de07b8a14e37279800 (patch)
tree003824e2639ba00636e3133d2f991b62d8b79bdc /OpenSim/Region/ClientStack
parentMerge branch 'prioritization' of ssh://opensimulator.org/var/git/opensim into... (diff)
downloadopensim-SC-142008121e2e9c5ca5fca5de07b8a14e37279800.zip
opensim-SC-142008121e2e9c5ca5fca5de07b8a14e37279800.tar.gz
opensim-SC-142008121e2e9c5ca5fca5de07b8a14e37279800.tar.bz2
opensim-SC-142008121e2e9c5ca5fca5de07b8a14e37279800.tar.xz
* Change Util.FireAndForget to use ThreadPool.UnsafeQueueUserWorkItem(). This avoids .NET remoting and a managed->unmanaged->managed jump. Overall, a night and day performance difference
* Initialize the LLClientView prim full update queue to the number of prims in the scene for a big performance boost * Reordered some comparisons on hot code paths for a minor speed boost * Removed an unnecessary call to the expensive DateTime.Now function (if you *have* to get the current time as opposed to Environment.TickCount, always use DateTime.UtcNow) * Don't fire the queue empty callback for the Resend category * Run the outgoing packet handler thread loop for each client synchronously. It seems like more time was being spent doing the execution asynchronously, and it made deadlocks very difficult to track down * Rewrote some expensive math in LandObject.cs * Optimized EntityManager to only lock on operations that need locking, and use TryGetValue() where possible * Only update the attachment database when an object is attached or detached * Other small misc. performance improvements
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs88
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs2
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs9
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs19
4 files changed, 62 insertions, 56 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
index 1c463ea..b027882 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs
@@ -321,12 +321,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
321 private readonly IGroupsModule m_GroupsModule; 321 private readonly IGroupsModule m_GroupsModule;
322 322
323 private int m_cachedTextureSerial; 323 private int m_cachedTextureSerial;
324 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates = 324 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_avatarTerseUpdates;
325 new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>(); 325 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates;
326 private PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock> m_primTerseUpdates = 326 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates;
327 new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
328 private PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates =
329 new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>();
330 private int m_moneyBalance; 327 private int m_moneyBalance;
331 private int m_animationSequenceNumber = 1; 328 private int m_animationSequenceNumber = 1;
332 private bool m_SendLogoutPacketWhenClosing = true; 329 private bool m_SendLogoutPacketWhenClosing = true;
@@ -335,7 +332,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
335 332
336 protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>(); 333 protected Dictionary<PacketType, PacketMethod> m_packetHandlers = new Dictionary<PacketType, PacketMethod>();
337 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers 334 protected Dictionary<string, GenericMessage> m_genericPacketHandlers = new Dictionary<string, GenericMessage>(); //PauPaw:Local Generic Message handlers
338 protected IScene m_scene; 335 protected Scene m_scene;
339 protected LLImageManager m_imageManager; 336 protected LLImageManager m_imageManager;
340 protected string m_firstName; 337 protected string m_firstName;
341 protected string m_lastName; 338 protected string m_lastName;
@@ -408,16 +405,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
408 /// <summary> 405 /// <summary>
409 /// Constructor 406 /// Constructor
410 /// </summary> 407 /// </summary>
411 public LLClientView(EndPoint remoteEP, IScene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo, 408 public LLClientView(EndPoint remoteEP, Scene scene, LLUDPServer udpServer, LLUDPClient udpClient, AuthenticateResponse sessionInfo,
412 UUID agentId, UUID sessionId, uint circuitCode) 409 UUID agentId, UUID sessionId, uint circuitCode)
413 { 410 {
414 RegisterInterface<IClientIM>(this); 411 RegisterInterface<IClientIM>(this);
415 RegisterInterface<IClientChat>(this); 412 RegisterInterface<IClientChat>(this);
416 RegisterInterface<IClientIPEndpoint>(this); 413 RegisterInterface<IClientIPEndpoint>(this);
417 414
418 InitDefaultAnimations(); 415 InitDefaultAnimations();
419 416
420 m_scene = scene; 417 m_scene = scene;
418
419 m_avatarTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
420 m_primTerseUpdates = new PriorityQueue<double, ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
421 m_primFullUpdates = new PriorityQueue<double, ObjectUpdatePacket.ObjectDataBlock>(m_scene.Entities.Count);
422
421 m_assetService = m_scene.RequestModuleInterface<IAssetService>(); 423 m_assetService = m_scene.RequestModuleInterface<IAssetService>();
422 m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>(); 424 m_hyperAssets = m_scene.RequestModuleInterface<IHyperAssetService>();
423 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>(); 425 m_GroupsModule = scene.RequestModuleInterface<IGroupsModule>();
@@ -3288,10 +3290,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3288 } 3290 }
3289 3291
3290 Quaternion rotation = data.Rotation; 3292 Quaternion rotation = data.Rotation;
3291 3293 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3292 if (rotation.X == rotation.Y &&
3293 rotation.Y == rotation.Z &&
3294 rotation.Z == rotation.W && rotation.W == 0.0f)
3295 rotation = Quaternion.Identity; 3294 rotation = Quaternion.Identity;
3296 3295
3297 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data); 3296 ImprovedTerseObjectUpdatePacket.ObjectDataBlock terseBlock = CreateImprovedTerseBlock(data);
@@ -3377,15 +3376,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3377 } 3376 }
3378 3377
3379 Quaternion rotation = data.rotation; 3378 Quaternion rotation = data.rotation;
3379 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3380 rotation = Quaternion.Identity;
3380 3381
3381 if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD 3382 if (data.AttachPoint > 30 && data.ownerID != AgentId) // Someone else's HUD
3382 return; 3383 return;
3383 if (data.primShape.PCode == 9 && data.primShape.State != 0 && data.parentID == 0) 3384 if (data.primShape.State != 0 && data.parentID == 0 && data.primShape.PCode == 9)
3384 return; 3385 return;
3385 3386
3386 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0.0f)
3387 rotation = Quaternion.Identity;
3388
3389 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data); 3387 ObjectUpdatePacket.ObjectDataBlock objectData = CreatePrimUpdateBlock(data);
3390 3388
3391 lock (m_primFullUpdates.SyncRoot) 3389 lock (m_primFullUpdates.SyncRoot)
@@ -3397,7 +3395,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3397 ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 3395 ObjectUpdatePacket outPacket = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
3398 outPacket.Header.Zerocoded = true; 3396 outPacket.Header.Zerocoded = true;
3399 3397
3400 //outPacket.RegionData = new ObjectUpdatePacket.RegionDataBlock();
3401 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle; 3398 outPacket.RegionData.RegionHandle = Scene.RegionInfo.RegionHandle;
3402 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue); 3399 outPacket.RegionData.TimeDilation = (ushort)(Scene.TimeDilation * ushort.MaxValue);
3403 3400
@@ -3424,13 +3421,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
3424 } 3421 }
3425 3422
3426 Quaternion rotation = data.Rotation; 3423 Quaternion rotation = data.Rotation;
3424 if (rotation.W == 0.0f && rotation.X == 0.0f && rotation.Y == 0.0f && rotation.Z == 0.0f)
3425 rotation = Quaternion.Identity;
3427 3426
3428 if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD 3427 if (data.AttachPoint > 30 && data.OwnerID != AgentId) // Someone else's HUD
3429 return; 3428 return;
3430 3429
3431 if (rotation.X == rotation.Y && rotation.Y == rotation.Z && rotation.Z == rotation.W && rotation.W == 0)
3432 rotation = Quaternion.Identity;
3433
3434 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data); 3430 ImprovedTerseObjectUpdatePacket.ObjectDataBlock objectData = CreateImprovedTerseBlock(data);
3435 3431
3436 lock (m_primTerseUpdates.SyncRoot) 3432 lock (m_primTerseUpdates.SyncRoot)
@@ -10238,10 +10234,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10238 { 10234 {
10239 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id); 10235 internal delegate bool UpdatePriorityHandler(ref TPriority priority, uint local_id);
10240 10236
10241 private MinHeap<MinHeapItem>[] heaps = new MinHeap<MinHeapItem>[1]; 10237 private MinHeap<MinHeapItem>[] m_heaps = new MinHeap<MinHeapItem>[1];
10242 private Dictionary<uint, LookupItem> lookup_table = new Dictionary<uint, LookupItem>(); 10238 private Dictionary<uint, LookupItem> m_lookupTable;
10243 private Comparison<TPriority> comparison; 10239 private Comparison<TPriority> m_comparison;
10244 private object sync_root = new object(); 10240 private object m_syncRoot = new object();
10245 10241
10246 internal PriorityQueue() : 10242 internal PriorityQueue() :
10247 this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { } 10243 this(MinHeap<MinHeapItem>.DEFAULT_CAPACITY, Comparer<TPriority>.Default) { }
@@ -10255,19 +10251,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10255 this(capacity, new Comparison<TPriority>(comparer.Compare)) { } 10251 this(capacity, new Comparison<TPriority>(comparer.Compare)) { }
10256 internal PriorityQueue(int capacity, Comparison<TPriority> comparison) 10252 internal PriorityQueue(int capacity, Comparison<TPriority> comparison)
10257 { 10253 {
10258 for (int i = 0; i < heaps.Length; ++i) 10254 m_lookupTable = new Dictionary<uint, LookupItem>(capacity);
10259 heaps[i] = new MinHeap<MinHeapItem>(capacity); 10255
10260 this.comparison = comparison; 10256 for (int i = 0; i < m_heaps.Length; ++i)
10257 m_heaps[i] = new MinHeap<MinHeapItem>(capacity);
10258 this.m_comparison = comparison;
10261 } 10259 }
10262 10260
10263 internal object SyncRoot { get { return this.sync_root; } } 10261 internal object SyncRoot { get { return this.m_syncRoot; } }
10264 internal int Count 10262 internal int Count
10265 { 10263 {
10266 get 10264 get
10267 { 10265 {
10268 int count = 0; 10266 int count = 0;
10269 for (int i = 0; i < heaps.Length; ++i) 10267 for (int i = 0; i < m_heaps.Length; ++i)
10270 count = heaps[i].Count; 10268 count = m_heaps[i].Count;
10271 return count; 10269 return count;
10272 } 10270 }
10273 } 10271 }
@@ -10276,36 +10274,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10276 { 10274 {
10277 LookupItem item; 10275 LookupItem item;
10278 10276
10279 if (lookup_table.TryGetValue(local_id, out item)) 10277 if (m_lookupTable.TryGetValue(local_id, out item))
10280 { 10278 {
10281 item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.comparison); 10279 item.Heap[item.Handle] = new MinHeapItem(priority, value, local_id, this.m_comparison);
10282 return false; 10280 return false;
10283 } 10281 }
10284 else 10282 else
10285 { 10283 {
10286 item.Heap = heaps[0]; 10284 item.Heap = m_heaps[0];
10287 item.Heap.Add(new MinHeapItem(priority, value, local_id, this.comparison), ref item.Handle); 10285 item.Heap.Add(new MinHeapItem(priority, value, local_id, this.m_comparison), ref item.Handle);
10288 lookup_table.Add(local_id, item); 10286 m_lookupTable.Add(local_id, item);
10289 return true; 10287 return true;
10290 } 10288 }
10291 } 10289 }
10292 10290
10293 internal TValue Peek() 10291 internal TValue Peek()
10294 { 10292 {
10295 for (int i = 0; i < heaps.Length; ++i) 10293 for (int i = 0; i < m_heaps.Length; ++i)
10296 if (heaps[i].Count > 0) 10294 if (m_heaps[i].Count > 0)
10297 return heaps[i].Min().Value; 10295 return m_heaps[i].Min().Value;
10298 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString())); 10296 throw new InvalidOperationException(string.Format("The {0} is empty", this.GetType().ToString()));
10299 } 10297 }
10300 10298
10301 internal TValue Dequeue() 10299 internal TValue Dequeue()
10302 { 10300 {
10303 for (int i = 0; i < heaps.Length; ++i) 10301 for (int i = 0; i < m_heaps.Length; ++i)
10304 { 10302 {
10305 if (heaps[i].Count > 0) 10303 if (m_heaps[i].Count > 0)
10306 { 10304 {
10307 MinHeapItem item = heaps[i].RemoveMin(); 10305 MinHeapItem item = m_heaps[i].RemoveMin();
10308 lookup_table.Remove(item.LocalID); 10306 m_lookupTable.Remove(item.LocalID);
10309 return item.Value; 10307 return item.Value;
10310 } 10308 }
10311 } 10309 }
@@ -10317,7 +10315,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10317 MinHeapItem item; 10315 MinHeapItem item;
10318 TPriority priority; 10316 TPriority priority;
10319 10317
10320 foreach (LookupItem lookup in new List<LookupItem>(this.lookup_table.Values)) 10318 foreach (LookupItem lookup in new List<LookupItem>(this.m_lookupTable.Values))
10321 { 10319 {
10322 if (lookup.Heap.TryGetValue(lookup.Handle, out item)) 10320 if (lookup.Heap.TryGetValue(lookup.Handle, out item))
10323 { 10321 {
@@ -10332,7 +10330,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
10332 { 10330 {
10333 m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update"); 10331 m_log.Warn("[LLCLIENTVIEW]: UpdatePriorityHandler returned false, dropping update");
10334 lookup.Heap.Remove(lookup.Handle); 10332 lookup.Heap.Remove(lookup.Handle);
10335 this.lookup_table.Remove(item.LocalID); 10333 this.m_lookupTable.Remove(item.LocalID);
10336 } 10334 }
10337 } 10335 }
10338 } 10336 }
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
index d25bf95..938cf50 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLImageManager.cs
@@ -51,7 +51,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
51 51
52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 52 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
53 private bool m_shuttingdown; 53 private bool m_shuttingdown;
54 private long m_lastloopprocessed;
55 private AssetBase m_missingImage; 54 private AssetBase m_missingImage;
56 private LLClientView m_client; //Client we're assigned to 55 private LLClientView m_client; //Client we're assigned to
57 private IAssetService m_assetCache; //Asset Cache 56 private IAssetService m_assetCache; //Asset Cache
@@ -169,7 +168,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
169 168
170 public bool ProcessImageQueue(int packetsToSend) 169 public bool ProcessImageQueue(int packetsToSend)
171 { 170 {
172 m_lastloopprocessed = DateTime.Now.Ticks;
173 int packetsSent = 0; 171 int packetsSent = 0;
174 172
175 while (packetsSent < packetsToSend) 173 while (packetsSent < packetsToSend)
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
index 9476eed..4b6a358 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs
@@ -506,8 +506,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
506 /// for</param> 506 /// for</param>
507 private void BeginFireQueueEmpty(int throttleIndex) 507 private void BeginFireQueueEmpty(int throttleIndex)
508 { 508 {
509 if (!m_onQueueEmptyRunning[throttleIndex]) 509 // Unknown is -1 and Resend is 0. Make sure we are only firing the
510 Util.FireAndForget(FireQueueEmpty, throttleIndex); 510 // callback for categories other than those
511 if (throttleIndex > 0)
512 {
513 if (!m_onQueueEmptyRunning[throttleIndex])
514 Util.FireAndForget(FireQueueEmpty, throttleIndex);
515 }
511 } 516 }
512 517
513 /// <summary> 518 /// <summary>
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 66e1468..74175d0 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -107,7 +107,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
107 /// <summary>Manages authentication for agent circuits</summary> 107 /// <summary>Manages authentication for agent circuits</summary>
108 private AgentCircuitManager m_circuitManager; 108 private AgentCircuitManager m_circuitManager;
109 /// <summary>Reference to the scene this UDP server is attached to</summary> 109 /// <summary>Reference to the scene this UDP server is attached to</summary>
110 private IScene m_scene; 110 private Scene m_scene;
111 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary> 111 /// <summary>The X/Y coordinates of the scene this UDP server is attached to</summary>
112 private Location m_location; 112 private Location m_location;
113 /// <summary>The measured resolution of Environment.TickCount</summary> 113 /// <summary>The measured resolution of Environment.TickCount</summary>
@@ -184,15 +184,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
184 184
185 public void AddScene(IScene scene) 185 public void AddScene(IScene scene)
186 { 186 {
187 if (m_scene == null) 187 if (m_scene != null)
188 { 188 {
189 m_scene = scene; 189 m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene");
190 m_location = new Location(m_scene.RegionInfo.RegionHandle); 190 return;
191 } 191 }
192 else 192
193 if (!(scene is Scene))
193 { 194 {
194 m_log.Error("[LLUDPSERVER]: AddScene() called on an LLUDPServer that already has a scene"); 195 m_log.Error("[LLUDPSERVER]: AddScene() called with an unrecognized scene type " + scene.GetType());
196 return;
195 } 197 }
198
199 m_scene = (Scene)scene;
200 m_location = new Location(m_scene.RegionInfo.RegionHandle);
196 } 201 }
197 202
198 public bool HandlesRegion(Location x) 203 public bool HandlesRegion(Location x)
@@ -794,7 +799,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
794 elapsed500MS = 0; 799 elapsed500MS = 0;
795 } 800 }
796 801
797 m_scene.ClientManager.ForEach( 802 m_scene.ClientManager.ForEachSync(
798 delegate(IClientAPI client) 803 delegate(IClientAPI client)
799 { 804 {
800 if (client is LLClientView) 805 if (client is LLClientView)