aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs160
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs22
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs9
3 files changed, 102 insertions, 89 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
index 8d07bae..3793712 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLClientView.cs
@@ -347,12 +347,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
347 private const uint MaxTransferBytesPerPacket = 600; 347 private const uint MaxTransferBytesPerPacket = 600;
348 348
349 /// <value> 349 /// <value>
350 /// List used in construction of data blocks for an object update packet. This is to stop us having to
351 /// continually recreate it.
352 /// </value>
353 protected List<ObjectUpdatePacket.ObjectDataBlock> m_fullUpdateDataBlocksBuilder;
354
355 /// <value>
356 /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the 350 /// Maintain a record of all the objects killed. This allows us to stop an update being sent from the
357 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an 351 /// thread servicing the m_primFullUpdates queue after a kill. If this happens the object persists as an
358 /// ownerless phantom. 352 /// ownerless phantom.
@@ -511,7 +505,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
511 m_scene = scene; 505 m_scene = scene;
512 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count); 506 m_entityUpdates = new PriorityQueue(m_scene.Entities.Count);
513 m_entityProps = new PriorityQueue(m_scene.Entities.Count); 507 m_entityProps = new PriorityQueue(m_scene.Entities.Count);
514 m_fullUpdateDataBlocksBuilder = new List<ObjectUpdatePacket.ObjectDataBlock>();
515 m_killRecord = new List<uint>(); 508 m_killRecord = new List<uint>();
516// m_attachmentsSent = new HashSet<uint>(); 509// m_attachmentsSent = new HashSet<uint>();
517 510
@@ -594,13 +587,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
594 OutPacket(disable, ThrottleOutPacketType.Unknown); 587 OutPacket(disable, ThrottleOutPacketType.Unknown);
595 } 588 }
596 589
597 // Shutdown the image manager
598 ImageManager.Close();
599 590
600 // Fire the callback for this connection closing 591 // Fire the callback for this connection closing
601 if (OnConnectionClosed != null) 592 if (OnConnectionClosed != null)
602 OnConnectionClosed(this); 593 OnConnectionClosed(this);
603 594
595
604 // Flush all of the packets out of the UDP server for this client 596 // Flush all of the packets out of the UDP server for this client
605 if (m_udpServer != null) 597 if (m_udpServer != null)
606 m_udpServer.Flush(m_udpClient); 598 m_udpServer.Flush(m_udpClient);
@@ -615,8 +607,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
615 607
616 // Disable UDP handling for this client 608 // Disable UDP handling for this client
617 m_udpClient.Shutdown(); 609 m_udpClient.Shutdown();
618 610
619 611 m_udpClient.OnQueueEmpty -= HandleQueueEmpty;
612 m_udpClient.HasUpdates -= HandleHasUpdates;
613 m_udpClient.OnPacketStats -= PopulateStats;
614
615 // Shutdown the image manager
616 ImageManager.Close();
617 ImageManager = null;
618
619 m_entityUpdates = null;
620 m_entityProps = null;
621 m_killRecord.Clear();
622 GroupsInView.Clear();
623 m_scene = null;
620 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false)); 624 //m_log.InfoFormat("[CLIENTVIEW] Memory pre GC {0}", System.GC.GetTotalMemory(false));
621 //GC.Collect(); 625 //GC.Collect();
622 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true)); 626 //m_log.InfoFormat("[CLIENTVIEW] Memory post GC {0}", System.GC.GetTotalMemory(true));
@@ -814,7 +818,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
814 public void ProcessSpecificPacketAsync(object state) 818 public void ProcessSpecificPacketAsync(object state)
815 { 819 {
816 AsyncPacketProcess packetObject = (AsyncPacketProcess)state; 820 AsyncPacketProcess packetObject = (AsyncPacketProcess)state;
817 821
818 try 822 try
819 { 823 {
820 packetObject.result = packetObject.Method(packetObject.ClientView, packetObject.Pack); 824 packetObject.result = packetObject.Method(packetObject.ClientView, packetObject.Pack);
@@ -4095,19 +4099,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4095 ResendPrimUpdate(update); 4099 ResendPrimUpdate(update);
4096 } 4100 }
4097 4101
4102 private List<ObjectUpdatePacket.ObjectDataBlock> objectUpdateBlocks = new List<ObjectUpdatePacket.ObjectDataBlock>();
4103 private List<ObjectUpdateCompressedPacket.ObjectDataBlock> compressedUpdateBlocks = new List<ObjectUpdateCompressedPacket.ObjectDataBlock>();
4104 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4105 private List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> terseAgentUpdateBlocks = new List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>();
4106
4098 private void ProcessEntityUpdates(int maxUpdatesBytes) 4107 private void ProcessEntityUpdates(int maxUpdatesBytes)
4099 { 4108 {
4100 OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>> objectUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdatePacket.ObjectDataBlock>>();
4101 OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>> compressedUpdateBlocks = new OpenSim.Framework.Lazy<List<ObjectUpdateCompressedPacket.ObjectDataBlock>>();
4102 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
4103 OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>> terseAgentUpdateBlocks = new OpenSim.Framework.Lazy<List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock>>();
4104
4105 OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 4109 OpenSim.Framework.Lazy<List<EntityUpdate>> objectUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
4106 OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 4110 OpenSim.Framework.Lazy<List<EntityUpdate>> compressedUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
4107 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 4111 OpenSim.Framework.Lazy<List<EntityUpdate>> terseUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
4108 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>(); 4112 OpenSim.Framework.Lazy<List<EntityUpdate>> terseAgentUpdates = new OpenSim.Framework.Lazy<List<EntityUpdate>>();
4109 4113
4110
4111 // Check to see if this is a flush 4114 // Check to see if this is a flush
4112 if (maxUpdatesBytes <= 0) 4115 if (maxUpdatesBytes <= 0)
4113 { 4116 {
@@ -4328,7 +4331,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4328 ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity); 4331 ablock = CreateAvatarUpdateBlock((ScenePresence)update.Entity);
4329 else 4332 else
4330 ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId); 4333 ablock = CreatePrimUpdateBlock((SceneObjectPart)update.Entity, this.m_agentId);
4331 objectUpdateBlocks.Value.Add(ablock); 4334 objectUpdateBlocks.Add(ablock);
4332 objectUpdates.Value.Add(update); 4335 objectUpdates.Value.Add(update);
4333 maxUpdatesBytes -= ablock.Length; 4336 maxUpdatesBytes -= ablock.Length;
4334 4337
@@ -4337,7 +4340,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4337 { 4340 {
4338 ObjectUpdateCompressedPacket.ObjectDataBlock ablock = 4341 ObjectUpdateCompressedPacket.ObjectDataBlock ablock =
4339 CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags); 4342 CreateCompressedUpdateBlock((SceneObjectPart)update.Entity, updateFlags);
4340 compressedUpdateBlocks.Value.Add(ablock); 4343 compressedUpdateBlocks.Add(ablock);
4341 compressedUpdates.Value.Add(update); 4344 compressedUpdates.Value.Add(update);
4342 maxUpdatesBytes -= ablock.Length; 4345 maxUpdatesBytes -= ablock.Length;
4343 } 4346 }
@@ -4348,14 +4351,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4348 { 4351 {
4349 // ALL presence updates go into a special list 4352 // ALL presence updates go into a special list
4350 ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); 4353 ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
4351 terseAgentUpdateBlocks.Value.Add(ablock); 4354 terseAgentUpdateBlocks.Add(ablock);
4352 terseAgentUpdates.Value.Add(update); 4355 terseAgentUpdates.Value.Add(update);
4353 } 4356 }
4354 else 4357 else
4355 { 4358 {
4356 // Everything else goes here 4359 // Everything else goes here
4357 ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures)); 4360 ablock = CreateImprovedTerseBlock(update.Entity, updateFlags.HasFlag(PrimUpdateFlags.Textures));
4358 terseUpdateBlocks.Value.Add(ablock); 4361 terseUpdateBlocks.Add(ablock);
4359 terseUpdates.Value.Add(update); 4362 terseUpdates.Value.Add(update);
4360 } 4363 }
4361 maxUpdatesBytes -= ablock.Length; 4364 maxUpdatesBytes -= ablock.Length;
@@ -4366,74 +4369,69 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4366 4369
4367 #region Packet Sending 4370 #region Packet Sending
4368 4371
4369// const float TIME_DILATION = 1.0f;
4370 ushort timeDilation; 4372 ushort timeDilation;
4371// if(updatesThisCall > 0)
4372// timeDilation = Utils.FloatToUInt16(avgTimeDilation/updatesThisCall, 0.0f, 1.0f);
4373// else
4374// timeDilation = ushort.MaxValue; // 1.0;
4375 4373
4376 timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f); 4374 timeDilation = Utils.FloatToUInt16(m_scene.TimeDilation, 0.0f, 1.0f);
4377 4375
4378 if (terseAgentUpdateBlocks.IsValueCreated) 4376 if (terseAgentUpdateBlocks.Count > 0)
4379 { 4377 {
4380 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseAgentUpdateBlocks.Value;
4381
4382 ImprovedTerseObjectUpdatePacket packet 4378 ImprovedTerseObjectUpdatePacket packet
4383 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate); 4379 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ImprovedTerseObjectUpdate);
4384 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4380 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4385 packet.RegionData.TimeDilation = timeDilation; 4381 packet.RegionData.TimeDilation = timeDilation;
4386 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4382 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseAgentUpdateBlocks.Count];
4383
4384 for (int i = 0; i < terseAgentUpdateBlocks.Count; i++)
4385 packet.ObjectData[i] = terseAgentUpdateBlocks[i];
4387 4386
4388 for (int i = 0; i < blocks.Count; i++) 4387 terseAgentUpdateBlocks.Clear();
4389 packet.ObjectData[i] = blocks[i];
4390 4388
4391 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); }); 4389 OutPacket(packet, ThrottleOutPacketType.Unknown, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseAgentUpdates.Value, oPacket); });
4392 } 4390 }
4393 4391
4394 if (objectUpdateBlocks.IsValueCreated) 4392 if (objectUpdateBlocks.Count > 0)
4395 { 4393 {
4396 List<ObjectUpdatePacket.ObjectDataBlock> blocks = objectUpdateBlocks.Value;
4397
4398 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate); 4394 ObjectUpdatePacket packet = (ObjectUpdatePacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdate);
4399 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4395 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4400 packet.RegionData.TimeDilation = timeDilation; 4396 packet.RegionData.TimeDilation = timeDilation;
4401 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4397 packet.ObjectData = new ObjectUpdatePacket.ObjectDataBlock[objectUpdateBlocks.Count];
4402 4398
4403 for (int i = 0; i < blocks.Count; i++) 4399 for (int i = 0; i < objectUpdateBlocks.Count; i++)
4404 packet.ObjectData[i] = blocks[i]; 4400 packet.ObjectData[i] = objectUpdateBlocks[i];
4401
4402 objectUpdateBlocks.Clear();
4405 4403
4406 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); }); 4404 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(objectUpdates.Value, oPacket); });
4407 } 4405 }
4408 4406
4409 if (compressedUpdateBlocks.IsValueCreated) 4407 if (compressedUpdateBlocks.Count > 0)
4410 { 4408 {
4411 List<ObjectUpdateCompressedPacket.ObjectDataBlock> blocks = compressedUpdateBlocks.Value;
4412
4413 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed); 4409 ObjectUpdateCompressedPacket packet = (ObjectUpdateCompressedPacket)PacketPool.Instance.GetPacket(PacketType.ObjectUpdateCompressed);
4414 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4410 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4415 packet.RegionData.TimeDilation = timeDilation; 4411 packet.RegionData.TimeDilation = timeDilation;
4416 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[blocks.Count]; 4412 packet.ObjectData = new ObjectUpdateCompressedPacket.ObjectDataBlock[compressedUpdateBlocks.Count];
4413
4414 for (int i = 0; i < compressedUpdateBlocks.Count; i++)
4415 packet.ObjectData[i] = compressedUpdateBlocks[i];
4417 4416
4418 for (int i = 0; i < blocks.Count; i++) 4417 compressedUpdateBlocks.Clear();
4419 packet.ObjectData[i] = blocks[i];
4420 4418
4421 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); }); 4419 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(compressedUpdates.Value, oPacket); });
4422 } 4420 }
4423 4421
4424 if (terseUpdateBlocks.IsValueCreated) 4422 if (terseUpdateBlocks.Count > 0)
4425 { 4423 {
4426 List<ImprovedTerseObjectUpdatePacket.ObjectDataBlock> blocks = terseUpdateBlocks.Value;
4427
4428 ImprovedTerseObjectUpdatePacket packet 4424 ImprovedTerseObjectUpdatePacket packet
4429 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket( 4425 = (ImprovedTerseObjectUpdatePacket)PacketPool.Instance.GetPacket(
4430 PacketType.ImprovedTerseObjectUpdate); 4426 PacketType.ImprovedTerseObjectUpdate);
4431 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle; 4427 packet.RegionData.RegionHandle = m_scene.RegionInfo.RegionHandle;
4432 packet.RegionData.TimeDilation = timeDilation; 4428 packet.RegionData.TimeDilation = timeDilation;
4433 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[blocks.Count]; 4429 packet.ObjectData = new ImprovedTerseObjectUpdatePacket.ObjectDataBlock[terseUpdateBlocks.Count];
4434 4430
4435 for (int i = 0; i < blocks.Count; i++) 4431 for (int i = 0; i < terseUpdateBlocks.Count; i++)
4436 packet.ObjectData[i] = blocks[i]; 4432 packet.ObjectData[i] = terseUpdateBlocks[i];
4433
4434 terseUpdateBlocks.Clear();
4437 4435
4438 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); }); 4436 OutPacket(packet, ThrottleOutPacketType.Task, true, delegate(OutgoingPacket oPacket) { ResendPrimUpdates(terseUpdates.Value, oPacket); });
4439 } 4437 }
@@ -4828,21 +4826,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4828 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true)); 4826 m_entityProps.Enqueue(priority, new ObjectPropertyUpdate(entity,0,false,true));
4829 } 4827 }
4830 4828
4829 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> objectFamilyBlocks = new
4830 List<ObjectPropertiesFamilyPacket.ObjectDataBlock>();
4831 List<ObjectPropertiesPacket.ObjectDataBlock> objectPropertiesBlocks =
4832 new List<ObjectPropertiesPacket.ObjectDataBlock>();
4833 List<SceneObjectPart> needPhysics = new List<SceneObjectPart>();
4834
4831 private void ProcessEntityPropertyRequests(int maxUpdateBytes) 4835 private void ProcessEntityPropertyRequests(int maxUpdateBytes)
4832 { 4836 {
4833 OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>> objectFamilyBlocks = 4837// OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates =
4834 new OpenSim.Framework.Lazy<List<ObjectPropertiesFamilyPacket.ObjectDataBlock>>(); 4838// new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4835
4836 OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>> objectPropertiesBlocks =
4837 new OpenSim.Framework.Lazy<List<ObjectPropertiesPacket.ObjectDataBlock>>();
4838 4839
4839 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> familyUpdates = 4840// OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
4840 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>(); 4841// new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4841
4842 OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>> propertyUpdates =
4843 new OpenSim.Framework.Lazy<List<ObjectPropertyUpdate>>();
4844 4842
4845 List<SceneObjectPart> needPhysics = new List<SceneObjectPart>();
4846 4843
4847 EntityUpdate iupdate; 4844 EntityUpdate iupdate;
4848 Int32 timeinqueue; // this is just debugging code & can be dropped later 4845 Int32 timeinqueue; // this is just debugging code & can be dropped later
@@ -4860,8 +4857,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4860 { 4857 {
4861 SceneObjectPart sop = (SceneObjectPart)update.Entity; 4858 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4862 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags); 4859 ObjectPropertiesFamilyPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesFamilyBlock(sop,update.Flags);
4863 objectFamilyBlocks.Value.Add(objPropDB); 4860 objectFamilyBlocks.Add(objPropDB);
4864 familyUpdates.Value.Add(update); 4861// familyUpdates.Value.Add(update);
4865 maxUpdateBytes -= objPropDB.Length; 4862 maxUpdateBytes -= objPropDB.Length;
4866 } 4863 }
4867 } 4864 }
@@ -4873,23 +4870,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4873 SceneObjectPart sop = (SceneObjectPart)update.Entity; 4870 SceneObjectPart sop = (SceneObjectPart)update.Entity;
4874 needPhysics.Add(sop); 4871 needPhysics.Add(sop);
4875 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop); 4872 ObjectPropertiesPacket.ObjectDataBlock objPropDB = CreateObjectPropertiesBlock(sop);
4876 objectPropertiesBlocks.Value.Add(objPropDB); 4873 objectPropertiesBlocks.Add(objPropDB);
4877 propertyUpdates.Value.Add(update); 4874// propertyUpdates.Value.Add(update);
4878 maxUpdateBytes -= objPropDB.Length; 4875 maxUpdateBytes -= objPropDB.Length;
4879 } 4876 }
4880 } 4877 }
4881 } 4878 }
4882 4879
4883 if (objectPropertiesBlocks.IsValueCreated) 4880 if (objectPropertiesBlocks.Count > 0)
4884 { 4881 {
4885 List<ObjectPropertiesPacket.ObjectDataBlock> blocks = objectPropertiesBlocks.Value;
4886 List<ObjectPropertyUpdate> updates = propertyUpdates.Value;
4887
4888 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties); 4882 ObjectPropertiesPacket packet = (ObjectPropertiesPacket)PacketPool.Instance.GetPacket(PacketType.ObjectProperties);
4889 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[blocks.Count]; 4883 packet.ObjectData = new ObjectPropertiesPacket.ObjectDataBlock[objectPropertiesBlocks.Count];
4890 for (int i = 0; i < blocks.Count; i++) 4884 for (int i = 0; i < objectPropertiesBlocks.Count; i++)
4891 packet.ObjectData[i] = blocks[i]; 4885 packet.ObjectData[i] = objectPropertiesBlocks[i];
4892 4886
4887
4888 objectPropertiesBlocks.Clear();
4893 packet.Header.Zerocoded = true; 4889 packet.Header.Zerocoded = true;
4894 4890
4895 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4891 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
@@ -4898,7 +4894,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4898 //OutPacket(packet, ThrottleOutPacketType.Task, true, 4894 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4899 // delegate(OutgoingPacket oPacket) 4895 // delegate(OutgoingPacket oPacket)
4900 // { 4896 // {
4901 // ResendPropertyUpdates(updates, oPacket); 4897 // ResendPropertyUpdates(propertyUpdates.Value, oPacket);
4902 // }); 4898 // });
4903 OutPacket(packet, ThrottleOutPacketType.Task, true); 4899 OutPacket(packet, ThrottleOutPacketType.Task, true);
4904 4900
@@ -4909,23 +4905,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4909 // Int32 fpcnt = 0; 4905 // Int32 fpcnt = 0;
4910 // Int32 fbcnt = 0; 4906 // Int32 fbcnt = 0;
4911 4907
4912 if (objectFamilyBlocks.IsValueCreated) 4908 if (objectFamilyBlocks.Count > 0)
4913 { 4909 {
4914 List<ObjectPropertiesFamilyPacket.ObjectDataBlock> blocks = objectFamilyBlocks.Value;
4915
4916 // one packet per object block... uggh... 4910 // one packet per object block... uggh...
4917 for (int i = 0; i < blocks.Count; i++) 4911 for (int i = 0; i < objectFamilyBlocks.Count; i++)
4918 { 4912 {
4919 ObjectPropertiesFamilyPacket packet = 4913 ObjectPropertiesFamilyPacket packet =
4920 (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily); 4914 (ObjectPropertiesFamilyPacket)PacketPool.Instance.GetPacket(PacketType.ObjectPropertiesFamily);
4921 4915
4922 packet.ObjectData = blocks[i]; 4916 packet.ObjectData = objectFamilyBlocks[i];
4923 packet.Header.Zerocoded = true; 4917 packet.Header.Zerocoded = true;
4924 4918
4925 // Pass in the delegate so that if this packet needs to be resent, we send the current properties 4919 // Pass in the delegate so that if this packet needs to be resent, we send the current properties
4926 // of the object rather than the properties when the packet was created 4920 // of the object rather than the properties when the packet was created
4927 List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>(); 4921// List<ObjectPropertyUpdate> updates = new List<ObjectPropertyUpdate>();
4928 updates.Add(familyUpdates.Value[i]); 4922// updates.Add(familyUpdates.Value[i]);
4929 // HACK : Remove intelligent resending until it's fixed in core 4923 // HACK : Remove intelligent resending until it's fixed in core
4930 //OutPacket(packet, ThrottleOutPacketType.Task, true, 4924 //OutPacket(packet, ThrottleOutPacketType.Task, true,
4931 // delegate(OutgoingPacket oPacket) 4925 // delegate(OutgoingPacket oPacket)
@@ -4937,6 +4931,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4937 // fpcnt++; 4931 // fpcnt++;
4938 // fbcnt++; 4932 // fbcnt++;
4939 } 4933 }
4934 objectFamilyBlocks.Clear();
4940 } 4935 }
4941 4936
4942 if(needPhysics.Count > 0) 4937 if(needPhysics.Count > 0)
@@ -4962,6 +4957,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
4962 4957
4963 eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId); 4958 eq.Enqueue(BuildEvent("ObjectPhysicsProperties", llsdBody),AgentId);
4964 } 4959 }
4960 needPhysics.Clear();
4965 } 4961 }
4966 4962
4967 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt); 4963 // m_log.WarnFormat("[PACKETCOUNTS] queued {0} property packets with {1} blocks",ppcnt,pbcnt);
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
index d59b761..e85cee2 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPClient.cs
@@ -120,13 +120,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
120 /// <summary>Circuit code that this client is connected on</summary> 120 /// <summary>Circuit code that this client is connected on</summary>
121 public readonly uint CircuitCode; 121 public readonly uint CircuitCode;
122 /// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary> 122 /// <summary>Sequence numbers of packets we've received (for duplicate checking)</summary>
123 public readonly IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200); 123 public IncomingPacketHistoryCollection PacketArchive = new IncomingPacketHistoryCollection(200);
124 124
125 /// <summary>Packets we have sent that need to be ACKed by the client</summary> 125 /// <summary>Packets we have sent that need to be ACKed by the client</summary>
126 public readonly UnackedPacketCollection NeedAcks = new UnackedPacketCollection(); 126 public UnackedPacketCollection NeedAcks = new UnackedPacketCollection();
127 127
128 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary> 128 /// <summary>ACKs that are queued up, waiting to be sent to the client</summary>
129 public readonly DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>(); 129 public DoubleLocklessQueue<uint> PendingAcks = new DoubleLocklessQueue<uint>();
130 130
131 /// <summary>Current packet sequence number</summary> 131 /// <summary>Current packet sequence number</summary>
132 public int CurrentSequence; 132 public int CurrentSequence;
@@ -170,7 +170,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
170 private double m_nextOnQueueEmpty = 0; 170 private double m_nextOnQueueEmpty = 0;
171 171
172 /// <summary>Throttle bucket for this agent's connection</summary> 172 /// <summary>Throttle bucket for this agent's connection</summary>
173 private readonly AdaptiveTokenBucket m_throttleClient; 173 private AdaptiveTokenBucket m_throttleClient;
174 public AdaptiveTokenBucket FlowThrottle 174 public AdaptiveTokenBucket FlowThrottle
175 { 175 {
176 get { return m_throttleClient; } 176 get { return m_throttleClient; }
@@ -179,10 +179,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
179 /// <summary>Throttle buckets for each packet category</summary> 179 /// <summary>Throttle buckets for each packet category</summary>
180 private readonly TokenBucket[] m_throttleCategories; 180 private readonly TokenBucket[] m_throttleCategories;
181 /// <summary>Outgoing queues for throttled packets</summary> 181 /// <summary>Outgoing queues for throttled packets</summary>
182 private readonly DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT]; 182 private DoubleLocklessQueue<OutgoingPacket>[] m_packetOutboxes = new DoubleLocklessQueue<OutgoingPacket>[THROTTLE_CATEGORY_COUNT];
183 /// <summary>A container that can hold one packet for each outbox, used to store 183 /// <summary>A container that can hold one packet for each outbox, used to store
184 /// dequeued packets that are being held for throttling</summary> 184 /// dequeued packets that are being held for throttling</summary>
185 private readonly OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT]; 185 private OutgoingPacket[] m_nextPackets = new OutgoingPacket[THROTTLE_CATEGORY_COUNT];
186 /// <summary>A reference to the LLUDPServer that is managing this client</summary> 186 /// <summary>A reference to the LLUDPServer that is managing this client</summary>
187 private readonly LLUDPServer m_udpServer; 187 private readonly LLUDPServer m_udpServer;
188 188
@@ -288,14 +288,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
288 for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++) 288 for (int i = 0; i < THROTTLE_CATEGORY_COUNT; i++)
289 { 289 {
290 m_packetOutboxes[i].Clear(); 290 m_packetOutboxes[i].Clear();
291 m_throttleCategories[i] = null;
291 m_nextPackets[i] = null; 292 m_nextPackets[i] = null;
292 } 293 }
293 294
294 // pull the throttle out of the scene throttle 295 // pull the throttle out of the scene throttle
295 m_throttleClient.Parent.UnregisterRequest(m_throttleClient); 296 m_throttleClient.Parent.UnregisterRequest(m_throttleClient);
297 m_throttleClient = null;
296 OnPacketStats = null; 298 OnPacketStats = null;
297 OnQueueEmpty = null; 299 OnQueueEmpty = null;
298 } 300 PendingAcks.Clear();
301 NeedAcks.Clear();
302 NeedAcks = null;
303 PendingAcks = null;
304 m_nextPackets = null;
305 m_packetOutboxes = null;
306 }
299 307
300 /// <summary> 308 /// <summary>
301 /// Gets information about this client connection 309 /// Gets information about this client connection
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
index b546a99..c9d5697 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/UnackedPacketCollection.cs
@@ -74,6 +74,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
74 /// <summary>Holds information about pending removals</summary> 74 /// <summary>Holds information about pending removals</summary>
75 private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>(); 75 private LocklessQueue<uint> m_pendingRemoves = new LocklessQueue<uint>();
76 76
77
78 public void Clear()
79 {
80 m_packets.Clear();
81 m_pendingAdds = null;
82 m_pendingAcknowledgements = null;
83 m_pendingRemoves = null;
84 }
85
77 /// <summary> 86 /// <summary>
78 /// Add an unacked packet to the collection 87 /// Add an unacked packet to the collection
79 /// </summary> 88 /// </summary>