aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/ClientStack
diff options
context:
space:
mode:
authorJustin Clark-Casey (justincc)2013-09-25 18:45:56 +0100
committerJustin Clark-Casey (justincc)2013-09-26 20:11:05 +0100
commit0114c8bd15f46746c3537e807262ba3533f0a6e1 (patch)
tree43e7560e547dda2256153318ffdaea68612b0cf8 /OpenSim/Region/ClientStack
parentReinsert 200ms sleep accidentally removed in commit 7dbc93c (Wed Sep 18 21:41... (diff)
downloadopensim-SC_OLD-0114c8bd15f46746c3537e807262ba3533f0a6e1.zip
opensim-SC_OLD-0114c8bd15f46746c3537e807262ba3533f0a6e1.tar.gz
opensim-SC_OLD-0114c8bd15f46746c3537e807262ba3533f0a6e1.tar.bz2
opensim-SC_OLD-0114c8bd15f46746c3537e807262ba3533f0a6e1.tar.xz
Reinsert client.SceneAgent checks into LLUDPServer.HandleCompleteMovementIntoRegion() to fix race condition regression in commit 7dbc93c (Wed Sep 18 21:41:51 2013 +0100)
This check is necessary to close a race condition where the CompleteAgentMovement processing could proceed when the UseCircuitCode thread had added the client to the client manager but before the ScenePresence had registered to process the CompleteAgentMovement message. This is most probably why the message appeared to get lost on a proportion of entity transfers. A better long term solution may be to set the IClientAPI.SceneAgent property before the client is added to the manager.
Diffstat (limited to 'OpenSim/Region/ClientStack')
-rw-r--r--OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs37
1 files changed, 26 insertions, 11 deletions
diff --git a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
index a130ffe..9504f15 100644
--- a/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
+++ b/OpenSim/Region/ClientStack/Linden/UDP/LLUDPServer.cs
@@ -1692,6 +1692,9 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1692 endPoint = (IPEndPoint)array[0]; 1692 endPoint = (IPEndPoint)array[0];
1693 CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1]; 1693 CompleteAgentMovementPacket packet = (CompleteAgentMovementPacket)array[1];
1694 1694
1695 m_log.DebugFormat(
1696 "[LLUDPSERVER]: Handling CompleteAgentMovement request from {0} in {1}", endPoint, m_scene.Name);
1697
1695 // Determine which agent this packet came from 1698 // Determine which agent this packet came from
1696 // We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination 1699 // We need to wait here because in when using the OpenSimulator V2 teleport protocol to travel to a destination
1697 // simulator with no existing child presence, the viewer (at least LL 3.3.4) will send UseCircuitCode 1700 // simulator with no existing child presence, the viewer (at least LL 3.3.4) will send UseCircuitCode
@@ -1703,24 +1706,36 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1703 { 1706 {
1704 if (m_scene.TryGetClient(endPoint, out client)) 1707 if (m_scene.TryGetClient(endPoint, out client))
1705 { 1708 {
1706 if (client.IsActive) 1709 if (!client.IsActive)
1707 {
1708 break;
1709 }
1710 else
1711 { 1710 {
1712 // This check exists to catch a condition where the client has been closed by another thread 1711 // This check exists to catch a condition where the client has been closed by another thread
1713 // but has not yet been removed from the client manager (and possibly a new connection has 1712 // but has not yet been removed from the client manager (and possibly a new connection has
1714 // not yet been established). 1713 // not yet been established).
1715 m_log.DebugFormat( 1714 m_log.DebugFormat(
1716 "[LLUDPSERVER]: Received a CompleteMovementIntoRegion from {0} for {1} in {2} but client is not active. Waiting.", 1715 "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active yet. Waiting.",
1716 endPoint, client.Name, m_scene.Name);
1717 }
1718 else if (client.SceneAgent == null)
1719 {
1720 // This check exists to catch a condition where the new client has been added to the client
1721 // manager but the SceneAgent has not yet been set in Scene.AddNewClient(). If we are too
1722 // eager, then the new ScenePresence may not have registered a listener for this messsage
1723 // before we try to process it.
1724 // XXX: A better long term fix may be to add the SceneAgent before the client is added to
1725 // the client manager
1726 m_log.DebugFormat(
1727 "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client SceneAgent not set yet. Waiting.",
1717 endPoint, client.Name, m_scene.Name); 1728 endPoint, client.Name, m_scene.Name);
1718 } 1729 }
1730 else
1731 {
1732 break;
1733 }
1719 } 1734 }
1720 else 1735 else
1721 { 1736 {
1722 m_log.DebugFormat( 1737 m_log.DebugFormat(
1723 "[LLUDPSERVER]: Received a CompleteMovementIntoRegion from {0} in {1} but no client exists. Waiting.", 1738 "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} in {1} but no client exists yet. Waiting.",
1724 endPoint, m_scene.Name); 1739 endPoint, m_scene.Name);
1725 } 1740 }
1726 1741
@@ -1730,19 +1745,19 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1730 if (client == null) 1745 if (client == null)
1731 { 1746 {
1732 m_log.DebugFormat( 1747 m_log.DebugFormat(
1733 "[LLUDPSERVER]: No client found for CompleteMovementIntoRegion from {0} in {1} after wait. Dropping.", 1748 "[LLUDPSERVER]: No client found for CompleteAgentMovement from {0} in {1} after wait. Dropping.",
1734 endPoint, m_scene.Name); 1749 endPoint, m_scene.Name);
1735 1750
1736 return; 1751 return;
1737 } 1752 }
1738 else if (!client.IsActive) 1753 else if (!client.IsActive || client.SceneAgent == null)
1739 { 1754 {
1740 // This check exists to catch a condition where the client has been closed by another thread 1755 // This check exists to catch a condition where the client has been closed by another thread
1741 // but has not yet been removed from the client manager. 1756 // but has not yet been removed from the client manager.
1742 // The packet could be simply ignored but it is useful to know if this condition occurred for other debugging 1757 // The packet could be simply ignored but it is useful to know if this condition occurred for other debugging
1743 // purposes. 1758 // purposes.
1744 m_log.DebugFormat( 1759 m_log.DebugFormat(
1745 "[LLUDPSERVER]: Received a CompleteMovementIntoRegion from {0} for {1} in {2} but client is not active after wait. Dropping.", 1760 "[LLUDPSERVER]: Received a CompleteAgentMovement from {0} for {1} in {2} but client is not active after wait. Dropping.",
1746 endPoint, client.Name, m_scene.Name); 1761 endPoint, client.Name, m_scene.Name);
1747 1762
1748 return; 1763 return;
@@ -1767,7 +1782,7 @@ namespace OpenSim.Region.ClientStack.LindenUDP
1767 catch (Exception e) 1782 catch (Exception e)
1768 { 1783 {
1769 m_log.ErrorFormat( 1784 m_log.ErrorFormat(
1770 "[LLUDPSERVER]: CompleteMovementIntoRegion handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}", 1785 "[LLUDPSERVER]: CompleteAgentMovement handling from endpoint {0}, client {1} {2} failed. Exception {3}{4}",
1771 endPoint != null ? endPoint.ToString() : "n/a", 1786 endPoint != null ? endPoint.ToString() : "n/a",
1772 client != null ? client.Name : "unknown", 1787 client != null ? client.Name : "unknown",
1773 client != null ? client.AgentId.ToString() : "unknown", 1788 client != null ? client.AgentId.ToString() : "unknown",