diff options
author | Dr Scofield | 2009-06-25 07:42:06 +0000 |
---|---|---|
committer | Dr Scofield | 2009-06-25 07:42:06 +0000 |
commit | afd5f76648740b80fdfe6cfdfca82e3def5baf03 (patch) | |
tree | 1adbd4b99be8e3c1fc0f38dcb4de08283f6d0f9d /OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |
parent | - fixes a "collection out of sync" exception in the ODE physics (diff) | |
download | opensim-SC-afd5f76648740b80fdfe6cfdfca82e3def5baf03.zip opensim-SC-afd5f76648740b80fdfe6cfdfca82e3def5baf03.tar.gz opensim-SC-afd5f76648740b80fdfe6cfdfca82e3def5baf03.tar.bz2 opensim-SC-afd5f76648740b80fdfe6cfdfca82e3def5baf03.tar.xz |
From: Alan Webb <alan_webb@us.ibm.com>
This change moves texture send processing out of the main
packet processing loop and moves it to a timer based
processing cycle.
Texture packets are sent to the client consistently over
time. The timer is discontinued whenever there are no
textures to transmit.
The behavior of the texture sending mechanism is controlled
by three variables in the LLCLient section of the config
file:
[1] TextureRequestRate (mS) determines how many times per second
texture send processing will occur. The default is 100mS.
[2] TextureSendLimit determines how many different textures
will be considered on each cycle. Textures are selected
by priority. The old mechanism specified a value of 10 for
this parameter and this is the default
[3] TextureDataLimit determines how many packets will be sent for
each of the selected textures. The old mechanism specified a
value of 5, so this is the default.
So the net effect is that TextureSendLimit*TextureDataLimit
packets will be sent every TextureRequestRate mS.
Once we have gotten a reasonable feeling for how these parameters
affect overall processing, it would be nice to autonmically manage
these values using information about the current status of the
region and network.
Note that this also resolves the pathologcal problem that
previously existed which was that a seated avatar generated very
few in-bound packets (theoretically) and would therefore be the
least able to retrieve the images being displayed by a
projector script.
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | 152 |
1 files changed, 123 insertions, 29 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs index cda4d49..2884268 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLClientView.cs | |||
@@ -80,6 +80,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
80 | private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = | 80 | private List<ObjectUpdatePacket.ObjectDataBlock> m_primFullUpdates = |
81 | new List<ObjectUpdatePacket.ObjectDataBlock>(); | 81 | new List<ObjectUpdatePacket.ObjectDataBlock>(); |
82 | 82 | ||
83 | private Timer m_textureRequestTimer; | ||
84 | |||
83 | private bool m_clientBlocked; | 85 | private bool m_clientBlocked; |
84 | 86 | ||
85 | private int m_probesWithNoIngressPackets; | 87 | private int m_probesWithNoIngressPackets; |
@@ -140,6 +142,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
140 | protected int m_primTerseUpdateRate = 10; | 142 | protected int m_primTerseUpdateRate = 10; |
141 | protected int m_primFullUpdateRate = 14; | 143 | protected int m_primFullUpdateRate = 14; |
142 | 144 | ||
145 | protected int m_textureRequestRate = 100; | ||
146 | protected int m_textureSendLimit = 10; | ||
147 | protected int m_textureDataLimit = 5; | ||
148 | |||
143 | protected int m_packetMTU = 1400; | 149 | protected int m_packetMTU = 1400; |
144 | 150 | ||
145 | protected IAssetService m_assetService; | 151 | protected IAssetService m_assetService; |
@@ -344,6 +350,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
344 | 350 | ||
345 | private readonly IGroupsModule m_GroupsModule; | 351 | private readonly IGroupsModule m_GroupsModule; |
346 | 352 | ||
353 | private AgentUpdateArgs lastarg = null; | ||
354 | |||
347 | //private TerrainUnacked handlerUnackedTerrain = null; | 355 | //private TerrainUnacked handlerUnackedTerrain = null; |
348 | 356 | ||
349 | //** | 357 | //** |
@@ -544,6 +552,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
544 | m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", | 552 | m_primFullUpdateRate = clientConfig.GetInt("FullUpdateRate", |
545 | m_primFullUpdateRate); | 553 | m_primFullUpdateRate); |
546 | 554 | ||
555 | m_textureRequestRate = clientConfig.GetInt("TextureRequestRate", | ||
556 | m_textureRequestRate); | ||
557 | |||
558 | m_textureSendLimit = clientConfig.GetInt("TextureSendLimit", | ||
559 | m_textureSendLimit); | ||
560 | |||
561 | m_textureDataLimit = clientConfig.GetInt("TextureDataLimit", | ||
562 | m_textureDataLimit); | ||
563 | |||
547 | m_packetMTU = clientConfig.GetInt("PacketMTU", 1400); | 564 | m_packetMTU = clientConfig.GetInt("PacketMTU", 1400); |
548 | } | 565 | } |
549 | } | 566 | } |
@@ -577,6 +594,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
577 | m_avatarTerseUpdateTimer.Stop(); | 594 | m_avatarTerseUpdateTimer.Stop(); |
578 | m_primTerseUpdateTimer.Stop(); | 595 | m_primTerseUpdateTimer.Stop(); |
579 | m_primFullUpdateTimer.Stop(); | 596 | m_primFullUpdateTimer.Stop(); |
597 | m_textureRequestTimer.Stop(); | ||
580 | 598 | ||
581 | // This is just to give the client a reasonable chance of | 599 | // This is just to give the client a reasonable chance of |
582 | // flushing out all it's packets. There should probably | 600 | // flushing out all it's packets. There should probably |
@@ -660,6 +678,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
660 | m_avatarTerseUpdateTimer.Stop(); | 678 | m_avatarTerseUpdateTimer.Stop(); |
661 | m_primTerseUpdateTimer.Stop(); | 679 | m_primTerseUpdateTimer.Stop(); |
662 | m_primFullUpdateTimer.Stop(); | 680 | m_primFullUpdateTimer.Stop(); |
681 | m_textureRequestTimer.Stop(); | ||
663 | } | 682 | } |
664 | 683 | ||
665 | public void Restart() | 684 | public void Restart() |
@@ -682,6 +701,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
682 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); | 701 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); |
683 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); | 702 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); |
684 | m_primFullUpdateTimer.AutoReset = false; | 703 | m_primFullUpdateTimer.AutoReset = false; |
704 | |||
705 | m_textureRequestTimer = new Timer(m_textureRequestRate); | ||
706 | m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests); | ||
707 | m_textureRequestTimer.AutoReset = false; | ||
708 | |||
685 | } | 709 | } |
686 | 710 | ||
687 | public void Terminate() | 711 | public void Terminate() |
@@ -914,6 +938,11 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
914 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); | 938 | m_primFullUpdateTimer = new Timer(m_primFullUpdateRate); |
915 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); | 939 | m_primFullUpdateTimer.Elapsed += new ElapsedEventHandler(ProcessPrimFullUpdates); |
916 | m_primFullUpdateTimer.AutoReset = false; | 940 | m_primFullUpdateTimer.AutoReset = false; |
941 | |||
942 | m_textureRequestTimer = new Timer(m_textureRequestRate); | ||
943 | m_textureRequestTimer.Elapsed += new ElapsedEventHandler(ProcessTextureRequests); | ||
944 | m_textureRequestTimer.AutoReset = false; | ||
945 | |||
917 | m_scene.AddNewClient(this); | 946 | m_scene.AddNewClient(this); |
918 | 947 | ||
919 | RefreshGroupMembership(); | 948 | RefreshGroupMembership(); |
@@ -985,6 +1014,26 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
985 | } | 1014 | } |
986 | } | 1015 | } |
987 | 1016 | ||
1017 | protected virtual void TextureRequestHandler() | ||
1018 | { | ||
1019 | m_log.DebugFormat("[TRH] Thread started"); | ||
1020 | while (m_imageManager != null) | ||
1021 | { | ||
1022 | try | ||
1023 | { | ||
1024 | while (m_imageManager != null) | ||
1025 | { | ||
1026 | } | ||
1027 | } | ||
1028 | catch (Exception e) | ||
1029 | { | ||
1030 | m_log.WarnFormat("[TRH] Exception in handler loop: {0}", e.Message); | ||
1031 | m_log.Debug(e); | ||
1032 | } | ||
1033 | } | ||
1034 | m_log.DebugFormat("[TRH] Thread terminated"); | ||
1035 | } | ||
1036 | |||
988 | # endregion | 1037 | # endregion |
989 | 1038 | ||
990 | // Previously ClientView.API partial class | 1039 | // Previously ClientView.API partial class |
@@ -3032,6 +3081,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3032 | } | 3081 | } |
3033 | } | 3082 | } |
3034 | 3083 | ||
3084 | // Unlike the other timers, this one is only started after | ||
3085 | // the first request is seen. | ||
3086 | |||
3087 | void ProcessTextureRequests(object sender, ElapsedEventArgs e) | ||
3088 | { | ||
3089 | if (m_imageManager != null) | ||
3090 | { | ||
3091 | if (m_imageManager.ProcessImageQueue(m_textureSendLimit, | ||
3092 | m_textureDataLimit)) | ||
3093 | { | ||
3094 | m_textureRequestTimer.Start(); | ||
3095 | } | ||
3096 | } | ||
3097 | } | ||
3098 | |||
3035 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) | 3099 | void ProcessPrimFullUpdates(object sender, ElapsedEventArgs e) |
3036 | { | 3100 | { |
3037 | lock (m_primFullUpdates) | 3101 | lock (m_primFullUpdates) |
@@ -3237,7 +3301,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3237 | ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec) | 3301 | ushort numParts, UUID ImageUUID, uint ImageSize, byte[] ImageData, byte imageCodec) |
3238 | { | 3302 | { |
3239 | ImageDataPacket im = new ImageDataPacket(); | 3303 | ImageDataPacket im = new ImageDataPacket(); |
3240 | im.Header.Reliable = true; | 3304 | im.Header.Reliable = false; |
3241 | im.ImageID.Packets = numParts; | 3305 | im.ImageID.Packets = numParts; |
3242 | im.ImageID.ID = ImageUUID; | 3306 | im.ImageID.ID = ImageUUID; |
3243 | 3307 | ||
@@ -3253,7 +3317,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
3253 | public void SendImageNextPart(ushort partNumber, UUID imageUuid, byte[] imageData) | 3317 | public void SendImageNextPart(ushort partNumber, UUID imageUuid, byte[] imageData) |
3254 | { | 3318 | { |
3255 | ImagePacketPacket im = new ImagePacketPacket(); | 3319 | ImagePacketPacket im = new ImagePacketPacket(); |
3256 | im.Header.Reliable = true; | 3320 | im.Header.Reliable = false; |
3257 | im.ImageID.Packet = partNumber; | 3321 | im.ImageID.Packet = partNumber; |
3258 | im.ImageID.ID = imageUuid; | 3322 | im.ImageID.ID = imageUuid; |
3259 | im.ImageData.Data = imageData; | 3323 | im.ImageData.Data = imageData; |
@@ -4727,14 +4791,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
4727 | /// <param name="Pack">OpenMetaverse.packet</param> | 4791 | /// <param name="Pack">OpenMetaverse.packet</param> |
4728 | public void ProcessInPacket(Packet Pack) | 4792 | public void ProcessInPacket(Packet Pack) |
4729 | { | 4793 | { |
4730 | // check if we've got a local packet handler for this packet.type. See RegisterLocalPacketHandlers() | 4794 | |
4731 | if (ProcessPacketMethod(Pack)) | 4795 | if (ProcessPacketMethod(Pack)) |
4732 | { | 4796 | { |
4733 | //there is a handler registered that handled this packet type | ||
4734 | |||
4735 | // in the end, we dereference this, so we have to check if it's null | ||
4736 | if (m_imageManager != null) | ||
4737 | m_imageManager.ProcessImageQueue(5); | ||
4738 | return; | 4797 | return; |
4739 | } | 4798 | } |
4740 | 4799 | ||
@@ -5303,6 +5362,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5303 | case PacketType.AgentUpdate: | 5362 | case PacketType.AgentUpdate: |
5304 | if (OnAgentUpdate != null) | 5363 | if (OnAgentUpdate != null) |
5305 | { | 5364 | { |
5365 | bool update = false; | ||
5306 | AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack; | 5366 | AgentUpdatePacket agenUpdate = (AgentUpdatePacket)Pack; |
5307 | 5367 | ||
5308 | #region Packet Session and User Check | 5368 | #region Packet Session and User Check |
@@ -5315,26 +5375,58 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
5315 | #endregion | 5375 | #endregion |
5316 | 5376 | ||
5317 | AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData; | 5377 | AgentUpdatePacket.AgentDataBlock x = agenUpdate.AgentData; |
5318 | AgentUpdateArgs arg = new AgentUpdateArgs(); | ||
5319 | arg.AgentID = x.AgentID; | ||
5320 | arg.BodyRotation = x.BodyRotation; | ||
5321 | arg.CameraAtAxis = x.CameraAtAxis; | ||
5322 | arg.CameraCenter = x.CameraCenter; | ||
5323 | arg.CameraLeftAxis = x.CameraLeftAxis; | ||
5324 | arg.CameraUpAxis = x.CameraUpAxis; | ||
5325 | arg.ControlFlags = x.ControlFlags; | ||
5326 | arg.Far = x.Far; | ||
5327 | arg.Flags = x.Flags; | ||
5328 | arg.HeadRotation = x.HeadRotation; | ||
5329 | arg.SessionID = x.SessionID; | ||
5330 | arg.State = x.State; | ||
5331 | 5378 | ||
5332 | handlerAgentUpdate = OnAgentUpdate; | 5379 | // We can only check when we have something to check |
5333 | if (handlerAgentUpdate != null) | 5380 | // against. |
5334 | OnAgentUpdate(this, arg); | 5381 | |
5382 | if (lastarg != null) | ||
5383 | { | ||
5384 | update = | ||
5385 | ( | ||
5386 | (x.BodyRotation != lastarg.BodyRotation) || | ||
5387 | (x.CameraAtAxis != lastarg.CameraAtAxis) || | ||
5388 | (x.CameraCenter != lastarg.CameraCenter) || | ||
5389 | (x.CameraLeftAxis != lastarg.CameraLeftAxis) || | ||
5390 | (x.CameraUpAxis != lastarg.CameraUpAxis) || | ||
5391 | (x.ControlFlags != lastarg.ControlFlags) || | ||
5392 | (x.Far != lastarg.Far) || | ||
5393 | (x.Flags != lastarg.Flags) || | ||
5394 | (x.State != lastarg.State) || | ||
5395 | (x.HeadRotation != lastarg.HeadRotation) || | ||
5396 | (x.SessionID != lastarg.SessionID) || | ||
5397 | (x.AgentID != lastarg.AgentID) | ||
5398 | ); | ||
5399 | } | ||
5400 | else | ||
5401 | update = true; | ||
5402 | |||
5403 | // These should be ordered from most-likely to | ||
5404 | // least likely to change. I've made an initial | ||
5405 | // guess at that. | ||
5406 | |||
5407 | if (update) | ||
5408 | { | ||
5409 | AgentUpdateArgs arg = new AgentUpdateArgs(); | ||
5410 | arg.AgentID = x.AgentID; | ||
5411 | arg.BodyRotation = x.BodyRotation; | ||
5412 | arg.CameraAtAxis = x.CameraAtAxis; | ||
5413 | arg.CameraCenter = x.CameraCenter; | ||
5414 | arg.CameraLeftAxis = x.CameraLeftAxis; | ||
5415 | arg.CameraUpAxis = x.CameraUpAxis; | ||
5416 | arg.ControlFlags = x.ControlFlags; | ||
5417 | arg.Far = x.Far; | ||
5418 | arg.Flags = x.Flags; | ||
5419 | arg.HeadRotation = x.HeadRotation; | ||
5420 | arg.SessionID = x.SessionID; | ||
5421 | arg.State = x.State; | ||
5422 | handlerAgentUpdate = OnAgentUpdate; | ||
5423 | lastarg = arg; // save this set of arguments for nexttime | ||
5424 | if (handlerAgentUpdate != null) | ||
5425 | OnAgentUpdate(this, arg); | ||
5426 | |||
5427 | handlerAgentUpdate = null; | ||
5428 | } | ||
5335 | 5429 | ||
5336 | handlerAgentUpdate = null; | ||
5337 | //agenUpdate.AgentData.ControlFlags, agenUpdate.AgentData.BodyRotationa); | ||
5338 | } | 5430 | } |
5339 | break; | 5431 | break; |
5340 | 5432 | ||
@@ -6392,10 +6484,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
6392 | 6484 | ||
6393 | // in the end, we null this, so we have to check if it's null | 6485 | // in the end, we null this, so we have to check if it's null |
6394 | if (m_imageManager != null) | 6486 | if (m_imageManager != null) |
6487 | { | ||
6395 | m_imageManager.EnqueueReq(args); | 6488 | m_imageManager.EnqueueReq(args); |
6489 | m_textureRequestTimer.Start(); | ||
6490 | } | ||
6396 | } | 6491 | } |
6397 | } | 6492 | } |
6398 | break; | 6493 | break; |
6494 | |||
6399 | case PacketType.TransferRequest: | 6495 | case PacketType.TransferRequest: |
6400 | //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request"); | 6496 | //m_log.Debug("ClientView.ProcessPackets.cs:ProcessInPacket() - Got transfer request"); |
6401 | 6497 | ||
@@ -9502,10 +9598,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
9502 | #endregion | 9598 | #endregion |
9503 | } | 9599 | } |
9504 | 9600 | ||
9505 | // in the end, we dereference this, so we have to check if it's null | ||
9506 | if (m_imageManager != null) | ||
9507 | m_imageManager.ProcessImageQueue(10); | ||
9508 | PacketPool.Instance.ReturnPacket(Pack); | 9601 | PacketPool.Instance.ReturnPacket(Pack); |
9602 | |||
9509 | } | 9603 | } |
9510 | 9604 | ||
9511 | private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) | 9605 | private static PrimitiveBaseShape GetShapeFromAddPacket(ObjectAddPacket addPacket) |