Avoid potential race conditions on UseCircuitCode. I artificially made the race condition happen, and got very similar results to those described in mantis #5365 -- no prims/avie sent back.

0.7.1-dev
Diva Canto 2011-02-08 17:53:01 -08:00
parent f431bd20ec
commit 117462cba1
1 changed files with 28 additions and 23 deletions

View File

@ -640,10 +640,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
{ {
object[] array = new object[] { buffer, packet }; object[] array = new object[] { buffer, packet };
if (m_asyncPacketHandling)
Util.FireAndForget(HandleUseCircuitCode, array); Util.FireAndForget(HandleUseCircuitCode, array);
else
HandleUseCircuitCode(array);
return; return;
} }
@ -857,12 +854,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint; IPEndPoint remoteEndPoint = (IPEndPoint)buffer.RemoteEndPoint;
// Acknowledge the UseCircuitCode packet immediately, even before processing further
// This is so that the client doesn't send another one
SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
// Begin the process of adding the client to the simulator // Begin the process of adding the client to the simulator
AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint); AddNewClient((UseCircuitCodePacket)packet, remoteEndPoint);
// Acknowledge the UseCircuitCode packet
SendAckImmediate(remoteEndPoint, packet.Header.Sequence);
// m_log.DebugFormat( // m_log.DebugFormat(
// "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms", // "[LLUDPSERVER]: Handling UseCircuitCode request from {0} took {1}ms",
// buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds); // buffer.RemoteEndPoint, (DateTime.Now - startTime).Milliseconds);
@ -927,12 +925,17 @@ namespace OpenSim.Region.ClientStack.LindenUDP
protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo) protected virtual void AddClient(uint circuitCode, UUID agentID, UUID sessionID, IPEndPoint remoteEndPoint, AuthenticateResponse sessionInfo)
{ {
// Create the LLUDPClient // In priciple there shouldn't be more than one thread here, ever.
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO); // But in case that happens, we need to synchronize this piece of code
// because it's too important
lock (this)
{
IClientAPI existingClient; IClientAPI existingClient;
if (!m_scene.TryGetClient(agentID, out existingClient)) if (!m_scene.TryGetClient(agentID, out existingClient))
{ {
// Create the LLUDPClient
LLUDPClient udpClient = new LLUDPClient(this, ThrottleRates, m_throttle, circuitCode, agentID, remoteEndPoint, m_defaultRTO, m_maxRTO);
// Create the LLClientView // Create the LLClientView
LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode); LLClientView client = new LLClientView(remoteEndPoint, m_scene, this, udpClient, sessionInfo, agentID, sessionID, circuitCode);
client.OnLogout += LogoutHandler; client.OnLogout += LogoutHandler;
@ -941,11 +944,13 @@ namespace OpenSim.Region.ClientStack.LindenUDP
// Start the IClientAPI // Start the IClientAPI
client.Start(); client.Start();
} }
else else
{ {
m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}", m_log.WarnFormat("[LLUDPSERVER]: Ignoring a repeated UseCircuitCode from {0} at {1} for circuit {2}",
udpClient.AgentID, remoteEndPoint, circuitCode); existingClient.AgentId, remoteEndPoint, circuitCode);
}
} }
} }