* Big performance increase in loading prims from the region database with MySQL

* Handle the AgentFOV packet
* Bypass queuing and throttles for ping checks to make ping times more closely match network latency
* Only track reliable bytes in LLUDPCLient.BytesSinceLastACK
This commit is contained in:
John Hurliman
2009-10-18 02:00:42 -07:00
parent a3f93cffb4
commit b4526a5a6d
4 changed files with 194 additions and 162 deletions

View File

@@ -295,6 +295,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
public event MuteListRequest OnMuteListRequest;
public event AvatarInterestUpdate OnAvatarInterestUpdate;
public event PlacesQuery OnPlacesQuery;
public event AgentFOV OnAgentFOV;
#endregion Events
@@ -346,6 +347,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected ulong m_activeGroupPowers;
protected Dictionary<UUID,ulong> m_groupPowers = new Dictionary<UUID, ulong>();
protected int m_terrainCheckerCount;
protected uint m_agentFOVCounter;
// These numbers are guesses at a decent tradeoff between responsiveness
// of the interest list and throughput. Lower is more responsive, higher
@@ -8871,20 +8873,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion
case PacketType.AgentFOV:
AgentFOVPacket fovPacket = (AgentFOVPacket)Pack;
if (fovPacket.FOVBlock.GenCounter > m_agentFOVCounter)
{
m_agentFOVCounter = fovPacket.FOVBlock.GenCounter;
AgentFOV handlerAgentFOV = OnAgentFOV;
if (handlerAgentFOV != null)
{
handlerAgentFOV(this, fovPacket.FOVBlock.VerticalAngle);
}
}
break;
#region unimplemented handlers
case PacketType.StartPingCheck:
StartPingCheckPacket pingStart = (StartPingCheckPacket)Pack;
CompletePingCheckPacket pingComplete = new CompletePingCheckPacket();
pingComplete.PingID.PingID = pingStart.PingID.PingID;
m_udpServer.SendPacket(m_udpClient, pingComplete, ThrottleOutPacketType.Unknown, false);
break;
case PacketType.CompletePingCheck:
// TODO: Do stats tracking or something with these?
break;
case PacketType.ViewerStats:
// TODO: handle this packet
//m_log.Warn("[CLIENT]: unhandled ViewerStats packet");

View File

@@ -572,6 +572,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < ackPacket.Packets.Length; i++)
AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent);
}
// We don't need to do anything else with PacketAck packets
return;
}
#endregion ACK Receiving
@@ -579,20 +582,22 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region ACK Sending
if (packet.Header.Reliable)
{
udpClient.PendingAcks.Enqueue(packet.Header.Sequence);
// This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
// add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove
// 2*MTU bytes from the value and send ACKs, and finally add the local value back to
// client.BytesSinceLastACK. Lockless thread safety
int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0);
bytesSinceLastACK += buffer.DataLength;
if (bytesSinceLastACK > LLUDPServer.MTU * 2)
{
bytesSinceLastACK -= LLUDPServer.MTU * 2;
SendAcks(udpClient);
// This is a somewhat odd sequence of steps to pull the client.BytesSinceLastACK value out,
// add the current received bytes to it, test if 2*MTU bytes have been sent, if so remove
// 2*MTU bytes from the value and send ACKs, and finally add the local value back to
// client.BytesSinceLastACK. Lockless thread safety
int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0);
bytesSinceLastACK += buffer.DataLength;
if (bytesSinceLastACK > LLUDPServer.MTU * 2)
{
bytesSinceLastACK -= LLUDPServer.MTU * 2;
SendAcks(udpClient);
}
Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK);
}
Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK);
#endregion ACK Sending
@@ -612,12 +617,28 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#endregion Incoming Packet Accounting
// Don't bother clogging up the queue with PacketAck packets that are already handled here
if (packet.Type != PacketType.PacketAck)
#region Ping Check Handling
if (packet.Type == PacketType.StartPingCheck)
{
// Inbox insertion
packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
// We don't need to do anything else with ping checks
StartPingCheckPacket startPing = (StartPingCheckPacket)packet;
CompletePingCheckPacket completePing = new CompletePingCheckPacket();
completePing.PingID.PingID = startPing.PingID.PingID;
SendPacket(udpClient, completePing, ThrottleOutPacketType.Unknown, false);
return;
}
else if (packet.Type == PacketType.CompletePingCheck)
{
// We don't currently track client ping times
return;
}
#endregion Ping Check Handling
// Inbox insertion
packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
}
protected override void PacketSent(UDPPacketBuffer buffer, int bytesSent)