aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
diff options
context:
space:
mode:
Diffstat (limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs')
-rw-r--r--OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs169
1 files changed, 145 insertions, 24 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index df8ddbb..584c577 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -27,6 +27,7 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Diagnostics;
30using System.IO; 31using System.IO;
31using System.Net; 32using System.Net;
32using System.Net.Sockets; 33using System.Net.Sockets;
@@ -506,7 +507,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
506 507
507 // Bump up the resend count on this packet 508 // Bump up the resend count on this packet
508 Interlocked.Increment(ref outgoingPacket.ResendCount); 509 Interlocked.Increment(ref outgoingPacket.ResendCount);
509 //Interlocked.Increment(ref Stats.ResentPackets);
510 510
511 // Requeue or resend the packet 511 // Requeue or resend the packet
512 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false)) 512 if (!outgoingPacket.Client.EnqueueOutgoing(outgoingPacket, false))
@@ -582,6 +582,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
582 udpClient.NeedAcks.Add(outgoingPacket); 582 udpClient.NeedAcks.Add(outgoingPacket);
583 } 583 }
584 } 584 }
585 else
586 {
587 Interlocked.Increment(ref udpClient.PacketsResent);
588 }
585 589
586 #endregion Sequence Number Assignment 590 #endregion Sequence Number Assignment
587 591
@@ -636,10 +640,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
636 { 640 {
637 object[] array = new object[] { buffer, packet }; 641 object[] array = new object[] { buffer, packet };
638 642
639 if (m_asyncPacketHandling) 643 Util.FireAndForget(HandleUseCircuitCode, array);
640 Util.FireAndForget(HandleUseCircuitCode, array);
641 else
642 HandleUseCircuitCode(array);
643 644
644 return; 645 return;
645 } 646 }
@@ -856,10 +857,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
856 // Begin the process of adding the client to the simulator 857 // Begin the process of adding the client to the simulator
857 AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); 858 AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
858 859
859 // Acknowledge the UseCircuitCode packet 860 // Send ack
860 SendAckImmediate(remoteEndPoint, packet.Header.Sequence); 861 SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
861 862
862// m_log.DebugFormat( 863 // m_log.DebugFormat(
863// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", 864// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
864// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); 865// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
865 } 866 }
@@ -923,25 +924,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
923 924
924 protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) 925 protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
925 { 926 {
926 // Create the LLUDPClient 927 // In priciple there shouldn't be more than one thread here, ever.
927 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); 928 // But in case that happens, we need to synchronize this piece of code
928 IClientAPI existingClient; 929 // because it's too important
929 930 lock (this)
930 if (!m_scene.TryGetClient(agentID, out existingClient))
931 { 931 {
932 // Create the LLClientView 932 IClientAPI existingClient;
933 LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
934 client.OnLogout += LogoutHandler;
935 933
936 client.DisableFacelights = m_disableFacelights; 934 if (!m_scene.TryGetClient(agentID, out existingClient))
935 {
936 // Create the LLUDPClient
937 LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
938 // Create the LLClientView
939 LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
940 client.OnLogout += LogoutHandler;
937 941
938 // Start the IClientAPI 942 client.DisableFacelights = m_disableFacelights;
939 client.Start(); 943
940 } 944 // Start the IClientAPI
941 else 945 client.Start();
942 { 946
943 m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}", 947 }
944 udpClient.AgentID, remoteEndPoint, circuitCode); 948 else
949 {
950 m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
951 existingClient.AgentId, remoteEndPoint, circuitCode);
952 }
945 } 953 }
946 } 954 }
947 955
@@ -1050,6 +1058,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1050 1058
1051 #endregion Update Timers 1059 #endregion Update Timers
1052 1060
1061 // Use this for emergency monitoring -- bug hunting
1062 //if (m_scene.EmergencyMonitoring)
1063 // clientPacketHandler = MonitoredClientOutgoingPacketHandler;
1064 //else
1065 // clientPacketHandler = ClientOutgoingPacketHandler;
1066
1053 // Handle outgoing packets, resends, acknowledgements, and pings for each 1067 // Handle outgoing packets, resends, acknowledgements, and pings for each
1054 // client. m_packetSent will be set to true if a packet is sent 1068 // client. m_packetSent will be set to true if a packet is sent
1055 m_scene.ForEachClient(clientPacketHandler); 1069 m_scene.ForEachClient(clientPacketHandler);
@@ -1065,6 +1079,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1065 { 1079 {
1066 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex); 1080 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
1067 } 1081 }
1082
1068 } 1083 }
1069 1084
1070 Watchdog.RemoveThread(); 1085 Watchdog.RemoveThread();
@@ -1102,6 +1117,112 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1102 } 1117 }
1103 } 1118 }
1104 1119
1120 #region Emergency Monitoring
1121 // Alternative packet handler fuull of instrumentation
1122 // Handy for hunting bugs
1123 private Stopwatch watch1 = new Stopwatch();
1124 private Stopwatch watch2 = new Stopwatch();
1125
1126 private float avgProcessingTicks = 0;
1127 private float avgResendUnackedTicks = 0;
1128 private float avgSendAcksTicks = 0;
1129 private float avgSendPingTicks = 0;
1130 private float avgDequeueTicks = 0;
1131 private long nticks = 0;
1132 private long nticksUnack = 0;
1133 private long nticksAck = 0;
1134 private long nticksPing = 0;
1135 private int npacksSent = 0;
1136 private int npackNotSent = 0;
1137
1138 private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
1139 {
1140 nticks++;
1141 watch1.Start();
1142 try
1143 {
1144 if (client is LLClientView)
1145 {
1146 LLUDPClient udpClient = ((LLClientView)client).UDPClient;
1147
1148 if (udpClient.IsConnected)
1149 {
1150 if (m_resendUnacked)
1151 {
1152 nticksUnack++;
1153 watch2.Start();
1154
1155 ResendUnacked(udpClient);
1156
1157 watch2.Stop();
1158 avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
1159 watch2.Reset();
1160 }
1161
1162 if (m_sendAcks)
1163 {
1164 nticksAck++;
1165 watch2.Start();
1166
1167 SendAcks(udpClient);
1168
1169 watch2.Stop();
1170 avgSendAcksTicks = (nticksAck - 1) / (float)nticksAck * avgSendAcksTicks + (watch2.ElapsedTicks / (float)nticksAck);
1171 watch2.Reset();
1172 }
1173
1174 if (m_sendPing)
1175 {
1176 nticksPing++;
1177 watch2.Start();
1178
1179 SendPing(udpClient);
1180
1181 watch2.Stop();
1182 avgSendPingTicks = (nticksPing - 1) / (float)nticksPing * avgSendPingTicks + (watch2.ElapsedTicks / (float)nticksPing);
1183 watch2.Reset();
1184 }
1185
1186 watch2.Start();
1187 // Dequeue any outgoing packets that are within the throttle limits
1188 if (udpClient.DequeueOutgoing())
1189 {
1190 m_packetSent = true;
1191 npacksSent++;
1192 }
1193 else
1194 npackNotSent++;
1195
1196 watch2.Stop();
1197 avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
1198 watch2.Reset();
1199
1200 }
1201 else
1202 m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
1203 }
1204 }
1205 catch (Exception ex)
1206 {
1207 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
1208 " threw an exception: " + ex.Message, ex);
1209 }
1210 watch1.Stop();
1211 avgProcessingTicks = (nticks - 1) / (float)nticks * avgProcessingTicks + (watch1.ElapsedTicks / (float)nticks);
1212 watch1.Reset();
1213
1214 // reuse this -- it's every ~100ms
1215 if (m_scene.EmergencyMonitoring && nticks % 100 == 0)
1216 {
1217 m_log.InfoFormat("[LLUDPSERVER]: avg processing ticks: {0} avg unacked: {1} avg acks: {2} avg ping: {3} avg dequeue: {4} (TickCountRes: {5} sent: {6} notsent: {7})",
1218 avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent);
1219 npackNotSent = npacksSent = 0;
1220 }
1221
1222 }
1223
1224 #endregion
1225
1105 private void ProcessInPacket(object state) 1226 private void ProcessInPacket(object state)
1106 { 1227 {
1107 IncomingPacket incomingPacket = (IncomingPacket)state; 1228 IncomingPacket incomingPacket = (IncomingPacket)state;