diff options
author | Kitto Flora | 2011-03-22 20:33:24 +0000 |
---|---|---|
committer | Kitto Flora | 2011-03-22 20:33:24 +0000 |
commit | 764e8c2a4371c24d1a0bd067c0bcbc806562064d (patch) | |
tree | 03dfb1bfe16c420fdbb6a1aa723c9203771d1beb /OpenSim/Region/ClientStack | |
parent | Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/ca... (diff) | |
parent | Add some more fields to Estate settings and make them work. (diff) | |
download | opensim-SC_OLD-764e8c2a4371c24d1a0bd067c0bcbc806562064d.zip opensim-SC_OLD-764e8c2a4371c24d1a0bd067c0bcbc806562064d.tar.gz opensim-SC_OLD-764e8c2a4371c24d1a0bd067c0bcbc806562064d.tar.bz2 opensim-SC_OLD-764e8c2a4371c24d1a0bd067c0bcbc806562064d.tar.xz |
Merge branch 'careminster-presence-refactor' of ssh://3dhosting.de/var/git/careminster into careminster-presence-refactor
Diffstat (limited to 'OpenSim/Region/ClientStack')
3 files changed, 171 insertions, 42 deletions
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs index f1fdbc5..d6159cd 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPClient.cs | |||
@@ -122,6 +122,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
122 | public int PacketsReceived; | 122 | public int PacketsReceived; |
123 | /// <summary>Number of packets sent to this client</summary> | 123 | /// <summary>Number of packets sent to this client</summary> |
124 | public int PacketsSent; | 124 | public int PacketsSent; |
125 | /// <summary>Number of packets resent to this client</summary> | ||
126 | public int PacketsResent; | ||
125 | /// <summary>Total byte count of unacked packets sent to this client</summary> | 127 | /// <summary>Total byte count of unacked packets sent to this client</summary> |
126 | public int UnackedBytes; | 128 | public int UnackedBytes; |
127 | 129 | ||
@@ -257,9 +259,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
257 | public string GetStats() | 259 | public string GetStats() |
258 | { | 260 | { |
259 | return string.Format( | 261 | return string.Format( |
260 | "{0,7} {1,7} {2,9} {3,8} {4,7} {5,7} {6,7} {7,7} {8,9} {9,7} {10,7}", | 262 | "{0,7} {1,7} {2,7} {3,9} {4,7} {5,7} {6,7} {7,7} {8,7} {9,8} {10,7} {11,7}", |
263 | PacketsReceived, | ||
261 | PacketsSent, | 264 | PacketsSent, |
262 | PacketsReceived, | 265 | PacketsResent, |
263 | UnackedBytes, | 266 | UnackedBytes, |
264 | m_packetOutboxes[(int)ThrottleOutPacketType.Resend].Count, | 267 | m_packetOutboxes[(int)ThrottleOutPacketType.Resend].Count, |
265 | m_packetOutboxes[(int)ThrottleOutPacketType.Land].Count, | 268 | m_packetOutboxes[(int)ThrottleOutPacketType.Land].Count, |
@@ -449,13 +452,16 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
449 | /// an outgoing packet from each, obeying the throttling bucket limits | 452 | /// an outgoing packet from each, obeying the throttling bucket limits |
450 | /// </summary> | 453 | /// </summary> |
451 | /// | 454 | /// |
455 | /// <remarks> | ||
452 | /// Packet queues are inspected in ascending numerical order starting from 0. Therefore, queues with a lower | 456 | /// Packet queues are inspected in ascending numerical order starting from 0. Therefore, queues with a lower |
453 | /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have | 457 | /// ThrottleOutPacketType number will see their packet get sent first (e.g. if both Land and Wind queues have |
454 | /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the | 458 | /// packets, then the packet at the front of the Land queue will be sent before the packet at the front of the |
455 | /// wind queue). | 459 | /// wind queue). |
456 | /// | 460 | /// |
457 | /// <remarks>This function is only called from a synchronous loop in the | 461 | /// This function is only called from a synchronous loop in the |
458 | /// UDPServer so we don't need to bother making this thread safe</remarks> | 462 | /// UDPServer so we don't need to bother making this thread safe |
463 | /// </remarks> | ||
464 | /// | ||
459 | /// <returns>True if any packets were sent, otherwise false</returns> | 465 | /// <returns>True if any packets were sent, otherwise false</returns> |
460 | public bool DequeueOutgoing() | 466 | public bool DequeueOutgoing() |
461 | { | 467 | { |
@@ -486,7 +492,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
486 | m_udpServer.SendPacketFinal(nextPacket); | 492 | m_udpServer.SendPacketFinal(nextPacket); |
487 | m_nextPackets[i] = null; | 493 | m_nextPackets[i] = null; |
488 | packetSent = true; | 494 | packetSent = true; |
489 | this.PacketsSent++; | ||
490 | } | 495 | } |
491 | } | 496 | } |
492 | else | 497 | else |
@@ -503,7 +508,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
503 | // Send the packet | 508 | // Send the packet |
504 | m_udpServer.SendPacketFinal(packet); | 509 | m_udpServer.SendPacketFinal(packet); |
505 | packetSent = true; | 510 | packetSent = true; |
506 | this.PacketsSent++; | ||
507 | } | 511 | } |
508 | else | 512 | else |
509 | { | 513 | { |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs index 703176c..c865c0f 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs | |||
@@ -27,6 +27,7 @@ | |||
27 | 27 | ||
28 | using System; | 28 | using System; |
29 | using System.Collections.Generic; | 29 | using System.Collections.Generic; |
30 | using System.Diagnostics; | ||
30 | using System.IO; | 31 | using System.IO; |
31 | using System.Net; | 32 | using System.Net; |
32 | using System.Net.Sockets; | 33 | using 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 | } |
@@ -844,7 +845,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
844 | 845 | ||
845 | private void HandleUseCircuitCode(object o) | 846 | private void HandleUseCircuitCode(object o) |
846 | { | 847 | { |
847 | DateTime startTime = DateTime.Now; | 848 | // DateTime startTime = DateTime.Now; |
848 | object[] array = (object[])o; | 849 | object[] array = (object[])o; |
849 | UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; | 850 | UDPPacketBuffer buffer = (UDPPacketBuffer)array[0]; |
850 | UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1]; | 851 | UseCircuitCodePacket packet = (UseCircuitCodePacket)array[1]; |
@@ -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 | ||
@@ -1052,6 +1060,12 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1052 | 1060 | ||
1053 | #endregion Update Timers | 1061 | #endregion Update Timers |
1054 | 1062 | ||
1063 | // Use this for emergency monitoring -- bug hunting | ||
1064 | //if (m_scene.EmergencyMonitoring) | ||
1065 | // clientPacketHandler = MonitoredClientOutgoingPacketHandler; | ||
1066 | //else | ||
1067 | // clientPacketHandler = ClientOutgoingPacketHandler; | ||
1068 | |||
1055 | // Handle outgoing packets, resends, acknowledgements, and pings for each | 1069 | // Handle outgoing packets, resends, acknowledgements, and pings for each |
1056 | // 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 |
1057 | m_scene.ForEachClient(clientPacketHandler); | 1071 | m_scene.ForEachClient(clientPacketHandler); |
@@ -1067,6 +1081,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1067 | { | 1081 | { |
1068 | 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); |
1069 | } | 1083 | } |
1084 | |||
1070 | } | 1085 | } |
1071 | 1086 | ||
1072 | Watchdog.RemoveThread(); | 1087 | Watchdog.RemoveThread(); |
@@ -1104,6 +1119,112 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
1104 | } | 1119 | } |
1105 | } | 1120 | } |
1106 | 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 | |||
1107 | private void ProcessInPacket(object state) | 1228 | private void ProcessInPacket(object state) |
1108 | { | 1229 | { |
1109 | IncomingPacket incomingPacket = (IncomingPacket)state; | 1230 | IncomingPacket incomingPacket = (IncomingPacket)state; |
diff --git a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs index 9d40688..d195110 100644 --- a/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs +++ b/OpenSim/Region/ClientStack/LindenUDP/UnackedPacketCollection.cs | |||
@@ -143,7 +143,8 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
143 | // Process all the pending adds | 143 | // Process all the pending adds |
144 | OutgoingPacket pendingAdd; | 144 | OutgoingPacket pendingAdd; |
145 | while (m_pendingAdds.TryDequeue(out pendingAdd)) | 145 | while (m_pendingAdds.TryDequeue(out pendingAdd)) |
146 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; | 146 | if (pendingAdd != null) |
147 | m_packets[pendingAdd.SequenceNumber] = pendingAdd; | ||
147 | 148 | ||
148 | // Process all the pending removes, including updating statistics and round-trip times | 149 | // Process all the pending removes, including updating statistics and round-trip times |
149 | PendingAck pendingRemove; | 150 | PendingAck pendingRemove; |
@@ -152,17 +153,20 @@ namespace OpenSim.Region.ClientStack.LindenUDP | |||
152 | { | 153 | { |
153 | if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) | 154 | if (m_packets.TryGetValue(pendingRemove.SequenceNumber, out ackedPacket)) |
154 | { | 155 | { |
155 | m_packets.Remove(pendingRemove.SequenceNumber); | 156 | if (ackedPacket != null) |
156 | |||
157 | // Update stats | ||
158 | Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); | ||
159 | |||
160 | if (!pendingRemove.FromResend) | ||
161 | { | 157 | { |
162 | // Calculate the round-trip time for this packet and its ACK | 158 | m_packets.Remove(pendingRemove.SequenceNumber); |
163 | int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; | 159 | |
164 | if (rtt > 0) | 160 | // Update stats |
165 | ackedPacket.Client.UpdateRoundTrip(rtt); | 161 | Interlocked.Add(ref ackedPacket.Client.UnackedBytes, -ackedPacket.Buffer.DataLength); |
162 | |||
163 | if (!pendingRemove.FromResend) | ||
164 | { | ||
165 | // Calculate the round-trip time for this packet and its ACK | ||
166 | int rtt = pendingRemove.RemoveTime - ackedPacket.TickCount; | ||
167 | if (rtt > 0) | ||
168 | ackedPacket.Client.UpdateRoundTrip(rtt); | ||
169 | } | ||
166 | } | 170 | } |
167 | } | 171 | } |
168 | } | 172 | } |