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.cs164
1 files changed, 141 insertions, 23 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index cfcc057..b7f9d87 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;
@@ -639,10 +640,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
639 { 640 {
640 object[] array = new object[] { buffer, packet }; 641 object[] array = new object[] { buffer, packet };
641 642
642 if (m_asyncPacketHandling) 643 Util.FireAndForget(HandleUseCircuitCode, array);
643 Util.FireAndForget(HandleUseCircuitCode, array);
644 else
645 HandleUseCircuitCode(array);
646 644
647 return; 645 return;
648 } 646 }
@@ -859,10 +857,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
859 // Begin the process of adding the client to the simulator 857 // Begin the process of adding the client to the simulator
860 AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); 858 AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
861 859
862 // Acknowledge the UseCircuitCode packet 860 // Send ack
863 SendAckImmediate(remoteEndPoint, packet.Header.Sequence); 861 SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
864 862
865// m_log.DebugFormat( 863 // m_log.DebugFormat(
866// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", 864// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
867// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); 865// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
868 } 866 }
@@ -926,25 +924,32 @@ namespace OpenSim.Region.ClientStack.LindenUDP
926 924
927 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)
928 { 926 {
929 // Create the LLUDPClient 927 // In priciple there shouldn't be more than one thread here, ever.
930 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
931 IClientAPI existingClient; 929 // because it's too important
932 930 lock (this)
933 if (!m_scene.TryGetClient(agentID, out existingClient))
934 { 931 {
935 // Create the LLClientView 932 IClientAPI existingClient;
936 LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
937 client.OnLogout += LogoutHandler;
938 933
939 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;
940 941
941 // Start the IClientAPI 942 client.DisableFacelights = m_disableFacelights;
942 client.Start(); 943
943 } 944 // Start the IClientAPI
944 else 945 client.Start();
945 { 946
946 m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}", 947 }
947 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 }
948 } 953 }
949 } 954 }
950 955
@@ -1055,6 +1060,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1055 1060
1056 #endregion Update Timers 1061 #endregion Update Timers
1057 1062
1063 // Use this for emergency monitoring -- bug hunting
1064 //if (m_scene.EmergencyMonitoring)
1065 // clientPacketHandler = MonitoredClientOutgoingPacketHandler;
1066 //else
1067 // clientPacketHandler = ClientOutgoingPacketHandler;
1068
1058 // Handle outgoing packets, resends, acknowledgements, and pings for each 1069 // Handle outgoing packets, resends, acknowledgements, and pings for each
1059 // client. m_packetSent will be set to true if a packet is sent 1070 // client. m_packetSent will be set to true if a packet is sent
1060 m_scene.ForEachClient(clientPacketHandler); 1071 m_scene.ForEachClient(clientPacketHandler);
@@ -1070,6 +1081,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1070 { 1081 {
1071 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex); 1082 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler loop threw an exception: " + ex.Message, ex);
1072 } 1083 }
1084
1073 } 1085 }
1074 1086
1075 Watchdog.RemoveThread(); 1087 Watchdog.RemoveThread();
@@ -1107,6 +1119,112 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1107 } 1119 }
1108 } 1120 }
1109 1121
1122 #region Emergency Monitoring
1123 // Alternative packet handler fuull of instrumentation
1124 // Handy for hunting bugs
1125 private Stopwatch watch1 = new Stopwatch();
1126 private Stopwatch watch2 = new Stopwatch();
1127
1128 private float avgProcessingTicks = 0;
1129 private float avgResendUnackedTicks = 0;
1130 private float avgSendAcksTicks = 0;
1131 private float avgSendPingTicks = 0;
1132 private float avgDequeueTicks = 0;
1133 private long nticks = 0;
1134 private long nticksUnack = 0;
1135 private long nticksAck = 0;
1136 private long nticksPing = 0;
1137 private int npacksSent = 0;
1138 private int npackNotSent = 0;
1139
1140 private void MonitoredClientOutgoingPacketHandler(IClientAPI client)
1141 {
1142 nticks++;
1143 watch1.Start();
1144 try
1145 {
1146 if (client is LLClientView)
1147 {
1148 LLUDPClient udpClient = ((LLClientView)client).UDPClient;
1149
1150 if (udpClient.IsConnected)
1151 {
1152 if (m_resendUnacked)
1153 {
1154 nticksUnack++;
1155 watch2.Start();
1156
1157 ResendUnacked(udpClient);
1158
1159 watch2.Stop();
1160 avgResendUnackedTicks = (nticksUnack - 1)/(float)nticksUnack * avgResendUnackedTicks + (watch2.ElapsedTicks / (float)nticksUnack);
1161 watch2.Reset();
1162 }
1163
1164 if (m_sendAcks)
1165 {
1166 nticksAck++;
1167 watch2.Start();
1168
1169 SendAcks(udpClient);
1170
1171 watch2.Stop();
1172 avgSendAcksTicks = (nticksAck - 1) / (float)nticksAck * avgSendAcksTicks + (watch2.ElapsedTicks / (float)nticksAck);
1173 watch2.Reset();
1174 }
1175
1176 if (m_sendPing)
1177 {
1178 nticksPing++;
1179 watch2.Start();
1180
1181 SendPing(udpClient);
1182
1183 watch2.Stop();
1184 avgSendPingTicks = (nticksPing - 1) / (float)nticksPing * avgSendPingTicks + (watch2.ElapsedTicks / (float)nticksPing);
1185 watch2.Reset();
1186 }
1187
1188 watch2.Start();
1189 // Dequeue any outgoing packets that are within the throttle limits
1190 if (udpClient.DequeueOutgoing())
1191 {
1192 m_packetSent = true;
1193 npacksSent++;
1194 }
1195 else
1196 npackNotSent++;
1197
1198 watch2.Stop();
1199 avgDequeueTicks = (nticks - 1) / (float)nticks * avgDequeueTicks + (watch2.ElapsedTicks / (float)nticks);
1200 watch2.Reset();
1201
1202 }
1203 else
1204 m_log.WarnFormat("[LLUDPSERVER]: Client is not connected");
1205 }
1206 }
1207 catch (Exception ex)
1208 {
1209 m_log.Error("[LLUDPSERVER]: OutgoingPacketHandler iteration for " + client.Name +
1210 " threw an exception: " + ex.Message, ex);
1211 }
1212 watch1.Stop();
1213 avgProcessingTicks = (nticks - 1) / (float)nticks * avgProcessingTicks + (watch1.ElapsedTicks / (float)nticks);
1214 watch1.Reset();
1215
1216 // reuse this -- it's every ~100ms
1217 if (m_scene.EmergencyMonitoring && nticks % 100 == 0)
1218 {
1219 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})",
1220 avgProcessingTicks, avgResendUnackedTicks, avgSendAcksTicks, avgSendPingTicks, avgDequeueTicks, TickCountResolution, npacksSent, npackNotSent);
1221 npackNotSent = npacksSent = 0;
1222 }
1223
1224 }
1225
1226 #endregion
1227
1110 private void ProcessInPacket(object state) 1228 private void ProcessInPacket(object state)
1111 { 1229 {
1112 IncomingPacket incomingPacket = (IncomingPacket)state; 1230 IncomingPacket incomingPacket = (IncomingPacket)state;