aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs107
1 files changed, 80 insertions, 27 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index a9f4b2c..74d3262 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -98,6 +98,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
98 98
99 /// <summary>The measured resolution of Environment.TickCount</summary> 99 /// <summary>The measured resolution of Environment.TickCount</summary>
100 public readonly float TickCountResolution; 100 public readonly float TickCountResolution;
101 /// <summary>Number of terse prim updates to put on the queue each time the
102 /// OnQueueEmpty event is triggered for updates</summary>
103 public readonly int PrimTerseUpdatesPerPacket;
104 /// <summary>Number of terse avatar updates to put on the queue each time the
105 /// OnQueueEmpty event is triggered for updates</summary>
106 public readonly int AvatarTerseUpdatesPerPacket;
107 /// <summary>Number of full prim updates to put on the queue each time the
108 /// OnQueueEmpty event is triggered for updates</summary>
109 public readonly int PrimFullUpdatesPerPacket;
110 /// <summary>Number of texture packets to put on the queue each time the
111 /// OnQueueEmpty event is triggered for textures</summary>
112 public readonly int TextureSendLimit;
101 113
102 /// <summary>Handlers for incoming packets</summary> 114 /// <summary>Handlers for incoming packets</summary>
103 //PacketEventDictionary packetEvents = new PacketEventDictionary(); 115 //PacketEventDictionary packetEvents = new PacketEventDictionary();
@@ -172,6 +184,18 @@ namespace OpenSim.Region.ClientStack.LindenUDP
172 m_asyncPacketHandling = config.GetBoolean("async_packet_handling", false); 184 m_asyncPacketHandling = config.GetBoolean("async_packet_handling", false);
173 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0); 185 m_recvBufferSize = config.GetInt("client_socket_rcvbuf_size", 0);
174 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0); 186 sceneThrottleBps = config.GetInt("scene_throttle_max_bps", 0);
187
188 PrimTerseUpdatesPerPacket = config.GetInt("PrimTerseUpdatesPerPacket", 25);
189 AvatarTerseUpdatesPerPacket = config.GetInt("AvatarTerseUpdatesPerPacket", 10);
190 PrimFullUpdatesPerPacket = config.GetInt("PrimFullUpdatesPerPacket", 100);
191 TextureSendLimit = config.GetInt("TextureSendLimit", 20);
192 }
193 else
194 {
195 PrimTerseUpdatesPerPacket = 25;
196 AvatarTerseUpdatesPerPacket = 10;
197 PrimFullUpdatesPerPacket = 100;
198 TextureSendLimit = 20;
175 } 199 }
176 200
177 m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps); 201 m_throttle = new TokenBucket(null, sceneThrottleBps, sceneThrottleBps);
@@ -187,14 +211,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
187 211
188 base.Start(m_recvBufferSize, m_asyncPacketHandling); 212 base.Start(m_recvBufferSize, m_asyncPacketHandling);
189 213
190 // Start the incoming packet processing thread 214 // Start the packet processing threads
191 Thread incomingThread = new Thread(IncomingPacketHandler); 215 Watchdog.StartThread(IncomingPacketHandler, "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false);
192 incomingThread.Name = "Incoming Packets (" + m_scene.RegionInfo.RegionName + ")"; 216 Watchdog.StartThread(OutgoingPacketHandler, "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")", ThreadPriority.Normal, false);
193 incomingThread.Start();
194
195 Thread outgoingThread = new Thread(OutgoingPacketHandler);
196 outgoingThread.Name = "Outgoing Packets (" + m_scene.RegionInfo.RegionName + ")";
197 outgoingThread.Start();
198 } 217 }
199 218
200 public new void Stop() 219 public new void Stop()
@@ -243,7 +262,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
243 for (int i = 0; i < packetCount; i++) 262 for (int i = 0; i < packetCount; i++)
244 { 263 {
245 byte[] data = datas[i]; 264 byte[] data = datas[i];
246 m_scene.ClientManager.ForEach( 265 m_scene.ForEachClient(
247 delegate(IClientAPI client) 266 delegate(IClientAPI client)
248 { 267 {
249 if (client is LLClientView) 268 if (client is LLClientView)
@@ -255,7 +274,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
255 else 274 else
256 { 275 {
257 byte[] data = packet.ToBytes(); 276 byte[] data = packet.ToBytes();
258 m_scene.ClientManager.ForEach( 277 m_scene.ForEachClient(
259 delegate(IClientAPI client) 278 delegate(IClientAPI client)
260 { 279 {
261 if (client is LLClientView) 280 if (client is LLClientView)
@@ -412,6 +431,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
412 { 431 {
413 m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO); 432 m_log.Debug("[LLUDPSERVER]: Resending " + expiredPackets.Count + " packets to " + udpClient.AgentID + ", RTO=" + udpClient.RTO);
414 433
434 // Exponential backoff of the retransmission timeout
435 udpClient.BackoffRTO();
436
415 // Resend packets 437 // Resend packets
416 for (int i = 0; i < expiredPackets.Count; i++) 438 for (int i = 0; i < expiredPackets.Count; i++)
417 { 439 {
@@ -548,27 +570,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
548 // UseCircuitCode handling 570 // UseCircuitCode handling
549 if (packet.Type == PacketType.UseCircuitCode) 571 if (packet.Type == PacketType.UseCircuitCode)
550 { 572 {
551 Util.FireAndForget( 573 m_log.Debug("[LLUDPSERVER]: Handling UseCircuitCode packet from " + buffer.RemoteEndPoint);
552 delegate(object o) 574 object[] array = new object[] { buffer, packet };
553 {
554 IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
555 575
556 // Begin the process of adding the client to the simulator 576 if (m_asyncPacketHandling)
557 AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); 577 Util.FireAndForget(HandleUseCircuitCode, array);
578 else
579 HandleUseCircuitCode(array);
558 580
559 // Acknowledge the UseCircuitCode packet
560 SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
561 }
562 );
563 return; 581 return;
564 } 582 }
565 583
566 // Determine which agent this packet came from 584 // Determine which agent this packet came from
567 IClientAPI client; 585 IClientAPI client;
568 if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView)) 586 if (!m_scene.TryGetClient(address, out client) || !(client is LLClientView))
569 { 587 {
570 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + 588 m_log.Debug("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address + " in " + m_scene.RegionInfo.RegionName);
571 " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients");
572 return; 589 return;
573 } 590 }
574 591
@@ -670,6 +687,21 @@ namespace OpenSim.Region.ClientStack.LindenUDP
670 packetInbox.Enqueue(new IncomingPacket(udpClient, packet)); 687 packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
671 } 688 }
672 689
690 private void HandleUseCircuitCode(object o)
691 {
692 object[] array = (object[])o;
693 UDPPacketBuffer buffer = (UDPPacketBuffer)array[0];
694 UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1];
695
696 IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
697
698 // Begin the process of adding the client to the simulator
699 AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
700
701 // Acknowledge the UseCircuitCode packet
702 SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
703 }
704
673 private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber) 705 private void SendAckImmediate(IPEndPoint remoteEndpoint, uint sequenceNumber)
674 { 706 {
675 PacketAckPacket ack = new PacketAckPacket(); 707 PacketAckPacket ack = new PacketAckPacket();
@@ -731,8 +763,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
731 { 763 {
732 // Create the LLUDPClient 764 // Create the LLUDPClient
733 LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint); 765 LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint);
766 IClientAPI existingClient;
734 767
735 if (!m_scene.ClientManager.ContainsKey(agentID)) 768 if (!m_scene.TryGetClient(agentID, out existingClient))
736 { 769 {
737 // Create the LLClientView 770 // Create the LLClientView
738 LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); 771 LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
@@ -752,7 +785,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
752 { 785 {
753 // Remove this client from the scene 786 // Remove this client from the scene
754 IClientAPI client; 787 IClientAPI client;
755 if (m_scene.ClientManager.TryGetValue(udpClient.AgentID, out client)) 788 if (m_scene.TryGetClient(udpClient.AgentID, out client))
756 client.Close(); 789 client.Close();
757 } 790 }
758 791
@@ -768,6 +801,14 @@ namespace OpenSim.Region.ClientStack.LindenUDP
768 { 801 {
769 IncomingPacket incomingPacket = null; 802 IncomingPacket incomingPacket = null;
770 803
804 // HACK: This is a test to try and rate limit packet handling on Mono.
805 // If it works, a more elegant solution can be devised
806 if (Util.FireAndForgetCount() < 2)
807 {
808 //m_log.Debug("[LLUDPSERVER]: Incoming packet handler is sleeping");
809 Thread.Sleep(30);
810 }
811
771 if (packetInbox.Dequeue(100, ref incomingPacket)) 812 if (packetInbox.Dequeue(100, ref incomingPacket))
772 Util.FireAndForget(ProcessInPacket, incomingPacket); 813 Util.FireAndForget(ProcessInPacket, incomingPacket);
773 } 814 }
@@ -775,11 +816,15 @@ namespace OpenSim.Region.ClientStack.LindenUDP
775 { 816 {
776 m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex); 817 m_log.Error("[LLUDPSERVER]: Error in the incoming packet handler loop: " + ex.Message, ex);
777 } 818 }
819
820 Watchdog.UpdateThread();
778 } 821 }
779 822
780 if (packetInbox.Count > 0) 823 if (packetInbox.Count > 0)
781 m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count + " packets"); 824 m_log.Warn("[LLUDPSERVER]: IncomingPacketHandler is shutting down, dropping " + packetInbox.Count + " packets");
782 packetInbox.Clear(); 825 packetInbox.Clear();
826
827 Watchdog.RemoveThread();
783 } 828 }
784 829
785 private void OutgoingPacketHandler() 830 private void OutgoingPacketHandler()
@@ -788,6 +833,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
788 // on to en-US to avoid number parsing issues 833 // on to en-US to avoid number parsing issues
789 Culture.SetCurrentCulture(); 834 Culture.SetCurrentCulture();
790 835
836 // Typecast the function to an Action<IClientAPI> once here to avoid allocating a new
837 // Action generic every round
838 Action<IClientAPI> clientPacketHandler = ClientOutgoingPacketHandler;
839
791 while (base.IsRunning) 840 while (base.IsRunning)
792 { 841 {
793 try 842 try
@@ -836,18 +885,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
836 885
837 // Handle outgoing packets, resends, acknowledgements, and pings for each 886 // Handle outgoing packets, resends, acknowledgements, and pings for each
838 // client. m_packetSent will be set to true if a packet is sent 887 // client. m_packetSent will be set to true if a packet is sent
839 m_scene.ClientManager.ForEachSync(ClientOutgoingPacketHandler); 888 m_scene.ForEachClient(clientPacketHandler, false);
840 889
841 // If nothing was sent, sleep for the minimum amount of time before a 890 // If nothing was sent, sleep for the minimum amount of time before a
842 // token bucket could get more tokens 891 // token bucket could get more tokens
843 if (!m_packetSent) 892 if (!m_packetSent)
844 Thread.Sleep((int)TickCountResolution); 893 Thread.Sleep((int)TickCountResolution);
894
895 Watchdog.UpdateThread();
845 } 896 }
846 catch (Exception ex) 897 catch (Exception ex)
847 { 898 {
848 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex); 899 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
849 } 900 }
850 } 901 }
902
903 Watchdog.RemoveThread();
851 } 904 }
852 905
853 private void ClientOutgoingPacketHandler(IClientAPI client) 906 private void ClientOutgoingPacketHandler(IClientAPI client)
@@ -897,7 +950,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
897 } 950 }
898 951
899 // Make sure this client is still alive 952 // Make sure this client is still alive
900 if (m_scene.ClientManager.TryGetValue(udpClient.AgentID, out client)) 953 if (m_scene.TryGetClient(udpClient.AgentID, out client))
901 { 954 {
902 try 955 try
903 { 956 {