From 23a334b9f54a1ef5df3b503c165e7b76b746a2b1 Mon Sep 17 00:00:00 2001
From: John Hurliman
Date: Tue, 13 Oct 2009 14:50:03 -0700
Subject: * Rewrote ClientManager to remove Lindenisms from OpenSim core,
improve performance by removing locks, and replace LLUDPClientCollection *
Removed the confusing (and LL-specific) shutdowncircuit parameter from
IClientAPI.Close() * Updated the LLUDP code to only use ClientManager instead
of trying to synchronize ClientManager and m_clients * Remove clients
asynchronously since it is a very slow operation (including a 2000ms sleep)
---
.../Region/ClientStack/LindenUDP/LLUDPServer.cs | 163 +++++++++++----------
1 file changed, 84 insertions(+), 79 deletions(-)
(limited to 'OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs')
diff --git a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
index 04c9cb1..8ec143a 100644
--- a/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/LindenUDP/LLUDPServer.cs
@@ -96,7 +96,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
/// Incoming packets that are awaiting handling
private OpenMetaverse.BlockingQueue packetInbox = new OpenMetaverse.BlockingQueue();
///
- private UDPClientCollection m_clients = new UDPClientCollection();
+ //private UDPClientCollection m_clients = new UDPClientCollection();
/// Bandwidth throttle for this UDP server
private TokenBucket m_throttle;
/// Bandwidth throttle rates for this UDP server
@@ -181,23 +181,6 @@ namespace OpenSim.Region.ClientStack.LindenUDP
return x == m_location;
}
- public void RemoveClient(LLUDPClient udpClient)
- {
- m_log.Debug("[LLUDPSERVER]: Removing LLUDPClient for " + udpClient.AgentID);
-
- // Shut down the IClientAPI and remove it from the scene
- IClientAPI client;
- if (m_scene.ClientManager.TryGetClient(udpClient.CircuitCode, out client))
- {
- client.Close(false);
- m_scene.ClientManager.Remove(udpClient.CircuitCode);
- }
-
- // Shut down the LLUDPClient and remove it from the list of UDP clients
- udpClient.Shutdown();
- m_clients.Remove(udpClient.RemoteEndPoint);
- }
-
public void BroadcastPacket(Packet packet, ThrottleOutPacketType category, bool sendToPausedAgents, bool allowSplitting)
{
// CoarseLocationUpdate packets cannot be split in an automated way
@@ -215,17 +198,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
for (int i = 0; i < packetCount; i++)
{
byte[] data = datas[i];
- m_clients.ForEach(
- delegate(LLUDPClient client)
- { SendPacketData(client, data, packet.Type, category); });
+ m_scene.ClientManager.ForEach(
+ delegate(IClientAPI client)
+ {
+ if (client is LLClientView)
+ SendPacketData(((LLClientView)client).UDPClient, data, packet.Type, category);
+ }
+ );
}
}
else
{
byte[] data = packet.ToBytes();
- m_clients.ForEach(
- delegate(LLUDPClient client)
- { SendPacketData(client, data, packet.Type, category); });
+ m_scene.ClientManager.ForEach(
+ delegate(IClientAPI client)
+ {
+ if (client is LLClientView)
+ SendPacketData(((LLClientView)client).UDPClient, data, packet.Type, category);
+ }
+ );
}
}
@@ -475,7 +466,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
//try { Thread.CurrentThread.Name = "PacketReceived (" + m_scene.RegionInfo.RegionName + ")"; }
//catch (Exception) { }
- LLUDPClient client = null;
+ LLUDPClient udpClient = null;
Packet packet = null;
int packetEnd = buffer.DataLength - 1;
IPEndPoint address = (IPEndPoint)buffer.RemoteEndPoint;
@@ -512,30 +503,33 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
// Determine which agent this packet came from
- if (!m_clients.TryGetValue(address, out client))
+ IClientAPI client;
+ if (!m_scene.ClientManager.TryGetValue(address, out client) || !(client is LLClientView))
{
m_log.Warn("[LLUDPSERVER]: Received a " + packet.Type + " packet from an unrecognized source: " + address +
- " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_clients.Count + " clients");
+ " in " + m_scene.RegionInfo.RegionName + ", currently tracking " + m_scene.ClientManager.Count + " clients");
return;
}
+ udpClient = ((LLClientView)client).UDPClient;
+
#endregion Packet to Client Mapping
// Stats tracking
- Interlocked.Increment(ref client.PacketsReceived);
+ Interlocked.Increment(ref udpClient.PacketsReceived);
#region ACK Receiving
int now = Environment.TickCount;
- client.TickLastPacketReceived = now;
+ udpClient.TickLastPacketReceived = now;
// Handle appended ACKs
if (packet.Header.AppendedAcks && packet.Header.AckList != null)
{
- lock (client.NeedAcks.SyncRoot)
+ lock (udpClient.NeedAcks.SyncRoot)
{
for (int i = 0; i < packet.Header.AckList.Length; i++)
- AcknowledgePacket(client, packet.Header.AckList[i], now, packet.Header.Resent);
+ AcknowledgePacket(udpClient, packet.Header.AckList[i], now, packet.Header.Resent);
}
}
@@ -544,10 +538,10 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{
PacketAckPacket ackPacket = (PacketAckPacket)packet;
- lock (client.NeedAcks.SyncRoot)
+ lock (udpClient.NeedAcks.SyncRoot)
{
for (int i = 0; i < ackPacket.Packets.Length; i++)
- AcknowledgePacket(client, ackPacket.Packets[i].ID, now, packet.Header.Resent);
+ AcknowledgePacket(udpClient, ackPacket.Packets[i].ID, now, packet.Header.Resent);
}
}
@@ -556,27 +550,27 @@ namespace OpenSim.Region.ClientStack.LindenUDP
#region ACK Sending
if (packet.Header.Reliable)
- client.PendingAcks.Enqueue(packet.Header.Sequence);
+ 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 client.BytesSinceLastACK, 0);
+ int bytesSinceLastACK = Interlocked.Exchange(ref udpClient.BytesSinceLastACK, 0);
bytesSinceLastACK += buffer.DataLength;
if (bytesSinceLastACK > Packet.MTU * 2)
{
bytesSinceLastACK -= Packet.MTU * 2;
- SendAcks(client);
+ SendAcks(udpClient);
}
- Interlocked.Add(ref client.BytesSinceLastACK, bytesSinceLastACK);
+ Interlocked.Add(ref udpClient.BytesSinceLastACK, bytesSinceLastACK);
#endregion ACK Sending
#region Incoming Packet Accounting
// Check the archive of received reliable packet IDs to see whether we already received this packet
- if (packet.Header.Reliable && !client.PacketArchive.TryEnqueue(packet.Header.Sequence))
+ if (packet.Header.Reliable && !udpClient.PacketArchive.TryEnqueue(packet.Header.Sequence))
{
if (packet.Header.Resent)
m_log.Debug("[LLUDPSERVER]: Received a resend of already processed packet #" + packet.Header.Sequence + ", type: " + packet.Type);
@@ -593,7 +587,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
if (packet.Type != PacketType.PacketAck)
{
// Inbox insertion
- packetInbox.Enqueue(new IncomingPacket(client, packet));
+ packetInbox.Enqueue(new IncomingPacket(udpClient, packet));
}
}
@@ -613,31 +607,23 @@ namespace OpenSim.Region.ClientStack.LindenUDP
private void AddNewClient(UseCircuitCodePacket useCircuitCode, IPEndPoint remoteEndPoint)
{
+ UUID agentID = useCircuitCode.CircuitCode.ID;
+ UUID sessionID = useCircuitCode.CircuitCode.SessionID;
+ uint circuitCode = useCircuitCode.CircuitCode.Code;
+
if (m_scene.RegionStatus != RegionStatus.SlaveScene)
{
- if (!m_clients.ContainsKey(remoteEndPoint))
+ AuthenticateResponse sessionInfo;
+ if (IsClientAuthorized(useCircuitCode, out sessionInfo))
{
- AuthenticateResponse sessionInfo;
- if (IsClientAuthorized(useCircuitCode, out sessionInfo))
- {
- UUID agentID = useCircuitCode.CircuitCode.ID;
- UUID sessionID = useCircuitCode.CircuitCode.SessionID;
- uint circuitCode = useCircuitCode.CircuitCode.Code;
-
- AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
- }
- else
- {
- // Don't create circuits for unauthorized clients
- m_log.WarnFormat(
- "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
- useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
- }
+ AddClient(circuitCode, agentID, sessionID, remoteEndPoint, sessionInfo);
}
else
{
- // Ignore repeated UseCircuitCode packets
- m_log.Debug("[LLUDPSERVER]: Ignoring UseCircuitCode for already established circuit " + useCircuitCode.CircuitCode.Code);
+ // Don't create circuits for unauthorized clients
+ m_log.WarnFormat(
+ "[LLUDPSERVER]: Connection request for client {0} connecting with unnotified circuit code {1} from {2}",
+ useCircuitCode.CircuitCode.ID, useCircuitCode.CircuitCode.Code, remoteEndPoint);
}
}
else
@@ -652,17 +638,31 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Create the LLUDPClient
LLUDPClient udpClient = new LLUDPClient(this, m_throttleRates, m_throttle, circuitCode, agentID, remoteEndPoint);
- // Create the LLClientView
- LLClientView clientApi = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
- clientApi.OnLogout += LogoutHandler;
- clientApi.OnConnectionClosed += ConnectionClosedHandler;
+ if (!m_scene.ClientManager.ContainsKey(agentID))
+ {
+ // Create the LLClientView
+ LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
+ client.OnLogout += LogoutHandler;
+ client.OnConnectionClosed += ConnectionClosedHandler;
- // Start the IClientAPI
- m_scene.ClientManager.Add(circuitCode, clientApi);
- clientApi.Start();
+ m_scene.ClientManager.Add(agentID, remoteEndPoint, client);
- // Add the new client to our list of tracked clients
- m_clients.Add(udpClient.RemoteEndPoint, udpClient);
+ // Start the IClientAPI
+ m_scene.ClientManager.Add(agentID, remoteEndPoint, client);
+ client.Start();
+ }
+ else
+ {
+ m_log.Debug("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from " + udpClient.AgentID);
+ }
+ }
+
+ private void RemoveClient(LLUDPClient udpClient)
+ {
+ // Remove this client from the scene ClientManager
+ IClientAPI client;
+ if (m_scene.ClientManager.TryGetValue(udpClient.AgentID, out client))
+ Util.FireAndForget(delegate(object o) { client.Close(); });
}
private void AcknowledgePacket(LLUDPClient client, uint ack, int currentTime, bool fromResend)
@@ -740,20 +740,25 @@ namespace OpenSim.Region.ClientStack.LindenUDP
elapsed500MS = 0;
}
- m_clients.ForEach(
- delegate(LLUDPClient client)
+ m_scene.ClientManager.ForEach(
+ delegate(IClientAPI client)
{
- if (client.DequeueOutgoing())
- packetSent = true;
- if (resendUnacked)
- ResendUnacked(client);
- if (sendAcks)
+ if (client is LLClientView)
{
- SendAcks(client);
- client.SendPacketStats();
+ LLUDPClient udpClient = ((LLClientView)client).UDPClient;
+
+ if (udpClient.DequeueOutgoing())
+ packetSent = true;
+ if (resendUnacked)
+ ResendUnacked(udpClient);
+ if (sendAcks)
+ {
+ SendAcks(udpClient);
+ udpClient.SendPacketStats();
+ }
+ if (sendPings)
+ SendPing(udpClient);
}
- if (sendPings)
- SendPing(client);
}
);
@@ -777,7 +782,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
}
// Make sure this client is still alive
- if (m_scene.ClientManager.TryGetClient(udpClient.CircuitCode, out client))
+ if (m_scene.ClientManager.TryGetValue(udpClient.AgentID, out client))
{
try
{
--
cgit v1.1