diff options
author | Justin Clarke Casey | 2008-05-07 22:59:30 +0000 |
---|---|---|
committer | Justin Clarke Casey | 2008-05-07 22:59:30 +0000 |
commit | be02107ea88885f377176937d7cbf5ec1b285c42 (patch) | |
tree | 22c3b557208e677cca493bedc845aa2a64d28b7d /OpenSim | |
parent | * Temporary fix for Mantis 1177. (diff) | |
download | opensim-SC_OLD-be02107ea88885f377176937d7cbf5ec1b285c42.zip opensim-SC_OLD-be02107ea88885f377176937d7cbf5ec1b285c42.tar.gz opensim-SC_OLD-be02107ea88885f377176937d7cbf5ec1b285c42.tar.bz2 opensim-SC_OLD-be02107ea88885f377176937d7cbf5ec1b285c42.tar.xz |
* Increasing ScenePresences locking to prevent race conditions such as those seen in one of the crashes of mantis 1163
* It's not impossible that this could lead to deadlock where sessions simply appear to freeze, even though the region console still responds.
* If this is the case, please file a mantis
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Environment/Scenes/InnerScene.cs | 39 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/Scene.cs | 168 | ||||
-rw-r--r-- | OpenSim/Region/Environment/Scenes/ScenePresence.cs | 1 |
3 files changed, 125 insertions, 83 deletions
diff --git a/OpenSim/Region/Environment/Scenes/InnerScene.cs b/OpenSim/Region/Environment/Scenes/InnerScene.cs index 80e71c8..9d4119d 100644 --- a/OpenSim/Region/Environment/Scenes/InnerScene.cs +++ b/OpenSim/Region/Environment/Scenes/InnerScene.cs | |||
@@ -116,7 +116,11 @@ namespace OpenSim.Region.Environment.Scenes | |||
116 | 116 | ||
117 | public void Close() | 117 | public void Close() |
118 | { | 118 | { |
119 | ScenePresences.Clear(); | 119 | lock (ScenePresences) |
120 | { | ||
121 | ScenePresences.Clear(); | ||
122 | } | ||
123 | |||
120 | //SceneObjects.Clear(); | 124 | //SceneObjects.Clear(); |
121 | Entities.Clear(); | 125 | Entities.Clear(); |
122 | } | 126 | } |
@@ -792,6 +796,8 @@ namespace OpenSim.Region.Environment.Scenes | |||
792 | /// <returns></returns> | 796 | /// <returns></returns> |
793 | public List<ScenePresence> GetScenePresences(FilterAvatarList filter) | 797 | public List<ScenePresence> GetScenePresences(FilterAvatarList filter) |
794 | { | 798 | { |
799 | // No locking of scene presences here since we're passing back a list... | ||
800 | |||
795 | List<ScenePresence> result = new List<ScenePresence>(); | 801 | List<ScenePresence> result = new List<ScenePresence>(); |
796 | List<ScenePresence> ScenePresencesList = GetScenePresences(); | 802 | List<ScenePresence> ScenePresencesList = GetScenePresences(); |
797 | 803 | ||
@@ -813,9 +819,12 @@ namespace OpenSim.Region.Environment.Scenes | |||
813 | /// <returns>null if the agent was not found</returns> | 819 | /// <returns>null if the agent was not found</returns> |
814 | public ScenePresence GetScenePresence(LLUUID agentID) | 820 | public ScenePresence GetScenePresence(LLUUID agentID) |
815 | { | 821 | { |
816 | if (ScenePresences.ContainsKey(agentID)) | 822 | lock (ScenePresences) |
817 | { | 823 | { |
818 | return ScenePresences[agentID]; | 824 | if (ScenePresences.ContainsKey(agentID)) |
825 | { | ||
826 | return ScenePresences[agentID]; | ||
827 | } | ||
819 | } | 828 | } |
820 | 829 | ||
821 | return null; | 830 | return null; |
@@ -917,16 +926,19 @@ namespace OpenSim.Region.Environment.Scenes | |||
917 | 926 | ||
918 | internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) | 927 | internal bool TryGetAvatarByName(string avatarName, out ScenePresence avatar) |
919 | { | 928 | { |
920 | foreach (ScenePresence presence in ScenePresences.Values) | 929 | lock (ScenePresences) |
921 | { | 930 | { |
922 | if (!presence.IsChildAgent) | 931 | foreach (ScenePresence presence in ScenePresences.Values) |
923 | { | 932 | { |
924 | string name = presence.ControllingClient.FirstName + " " + presence.ControllingClient.LastName; | 933 | if (!presence.IsChildAgent) |
925 | |||
926 | if (String.Compare(avatarName, name, true) == 0) | ||
927 | { | 934 | { |
928 | avatar = presence; | 935 | string name = presence.ControllingClient.FirstName + " " + presence.ControllingClient.LastName; |
929 | return true; | 936 | |
937 | if (String.Compare(avatarName, name, true) == 0) | ||
938 | { | ||
939 | avatar = presence; | ||
940 | return true; | ||
941 | } | ||
930 | } | 942 | } |
931 | } | 943 | } |
932 | } | 944 | } |
@@ -1008,9 +1020,12 @@ namespace OpenSim.Region.Environment.Scenes | |||
1008 | 1020 | ||
1009 | internal void ForEachClient(Action<IClientAPI> action) | 1021 | internal void ForEachClient(Action<IClientAPI> action) |
1010 | { | 1022 | { |
1011 | foreach (ScenePresence presence in ScenePresences.Values) | 1023 | lock (ScenePresences) |
1012 | { | 1024 | { |
1013 | action(presence.ControllingClient); | 1025 | foreach (ScenePresence presence in ScenePresences.Values) |
1026 | { | ||
1027 | action(presence.ControllingClient); | ||
1028 | } | ||
1014 | } | 1029 | } |
1015 | } | 1030 | } |
1016 | 1031 | ||
diff --git a/OpenSim/Region/Environment/Scenes/Scene.cs b/OpenSim/Region/Environment/Scenes/Scene.cs index 72512c7..ebbfece 100644 --- a/OpenSim/Region/Environment/Scenes/Scene.cs +++ b/OpenSim/Region/Environment/Scenes/Scene.cs | |||
@@ -2076,18 +2076,21 @@ namespace OpenSim.Region.Environment.Scenes | |||
2076 | { | 2076 | { |
2077 | if (regionHandle == m_regInfo.RegionHandle) | 2077 | if (regionHandle == m_regInfo.RegionHandle) |
2078 | { | 2078 | { |
2079 | if (m_scenePresences.ContainsKey(agentID)) | 2079 | lock (m_scenePresences) |
2080 | { | 2080 | { |
2081 | try | 2081 | if (m_scenePresences.ContainsKey(agentID)) |
2082 | { | ||
2083 | m_scenePresences[agentID].MakeRootAgent(position, isFlying); | ||
2084 | } | ||
2085 | catch (Exception e) | ||
2086 | { | 2082 | { |
2087 | m_log.Info("[SCENE]: Unable to do Agent Crossing."); | 2083 | try |
2088 | m_log.Debug("[SCENE]: " + e.ToString()); | 2084 | { |
2085 | m_scenePresences[agentID].MakeRootAgent(position, isFlying); | ||
2086 | } | ||
2087 | catch (Exception e) | ||
2088 | { | ||
2089 | m_log.Info("[SCENE]: Unable to do Agent Crossing."); | ||
2090 | m_log.Debug("[SCENE]: " + e.ToString()); | ||
2091 | } | ||
2092 | //m_innerScene.SwapRootChildAgent(false); | ||
2089 | } | 2093 | } |
2090 | //m_innerScene.SwapRootChildAgent(false); | ||
2091 | } | 2094 | } |
2092 | } | 2095 | } |
2093 | } | 2096 | } |
@@ -2203,10 +2206,13 @@ namespace OpenSim.Region.Environment.Scenes | |||
2203 | public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, | 2206 | public void RequestTeleportLocation(IClientAPI remoteClient, ulong regionHandle, LLVector3 position, |
2204 | LLVector3 lookAt, uint flags) | 2207 | LLVector3 lookAt, uint flags) |
2205 | { | 2208 | { |
2206 | if (m_scenePresences.ContainsKey(remoteClient.AgentId)) | 2209 | lock (m_scenePresences) |
2207 | { | 2210 | { |
2208 | m_sceneGridService.RequestTeleportToLocation(m_scenePresences[remoteClient.AgentId], regionHandle, | 2211 | if (m_scenePresences.ContainsKey(remoteClient.AgentId)) |
2209 | position, lookAt, flags); | 2212 | { |
2213 | m_sceneGridService.RequestTeleportToLocation(m_scenePresences[remoteClient.AgentId], regionHandle, | ||
2214 | position, lookAt, flags); | ||
2215 | } | ||
2210 | } | 2216 | } |
2211 | } | 2217 | } |
2212 | 2218 | ||
@@ -2218,10 +2224,13 @@ namespace OpenSim.Region.Environment.Scenes | |||
2218 | /// <param name="position"></param> | 2224 | /// <param name="position"></param> |
2219 | public void RequestTeleportLandmark(IClientAPI remoteClient, ulong regionHandle, LLVector3 position) | 2225 | public void RequestTeleportLandmark(IClientAPI remoteClient, ulong regionHandle, LLVector3 position) |
2220 | { | 2226 | { |
2221 | if (m_scenePresences.ContainsKey(remoteClient.AgentId)) | 2227 | lock (m_scenePresences) |
2222 | { | 2228 | { |
2223 | m_sceneGridService.RequestTeleportToLocation(m_scenePresences[remoteClient.AgentId], regionHandle, | 2229 | if (m_scenePresences.ContainsKey(remoteClient.AgentId)) |
2224 | position, LLVector3.Zero, 0); | 2230 | { |
2231 | m_sceneGridService.RequestTeleportToLocation(m_scenePresences[remoteClient.AgentId], regionHandle, | ||
2232 | position, LLVector3.Zero, 0); | ||
2233 | } | ||
2225 | } | 2234 | } |
2226 | } | 2235 | } |
2227 | 2236 | ||
@@ -2353,18 +2362,25 @@ namespace OpenSim.Region.Environment.Scenes | |||
2353 | public void SendUrlToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, bool groupOwned, | 2362 | public void SendUrlToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, bool groupOwned, |
2354 | string message, string url) | 2363 | string message, string url) |
2355 | { | 2364 | { |
2356 | if (m_scenePresences.ContainsKey(avatarID)) | 2365 | lock (m_scenePresences) |
2357 | { | 2366 | { |
2358 | m_scenePresences[avatarID].ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, | 2367 | if (m_scenePresences.ContainsKey(avatarID)) |
2359 | message, url); | 2368 | { |
2369 | m_scenePresences[avatarID].ControllingClient.SendLoadURL(objectName, objectID, ownerID, groupOwned, | ||
2370 | message, url); | ||
2371 | } | ||
2360 | } | 2372 | } |
2361 | } | 2373 | } |
2362 | 2374 | ||
2363 | public void SendDialogToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, string message, LLUUID TextureID, int ch, string[] buttonlabels) | 2375 | public void SendDialogToUser(LLUUID avatarID, string objectName, LLUUID objectID, LLUUID ownerID, string message, LLUUID TextureID, int ch, string[] buttonlabels) |
2364 | { | 2376 | { |
2365 | if (m_scenePresences.ContainsKey(avatarID)) | 2377 | lock (m_scenePresences) |
2366 | { | 2378 | { |
2367 | m_scenePresences[avatarID].ControllingClient.SendDialog(objectName, objectID, ownerID, message, TextureID, ch, buttonlabels); | 2379 | if (m_scenePresences.ContainsKey(avatarID)) |
2380 | { | ||
2381 | m_scenePresences[avatarID].ControllingClient.SendDialog( | ||
2382 | objectName, objectID, ownerID, message, TextureID, ch, buttonlabels); | ||
2383 | } | ||
2368 | } | 2384 | } |
2369 | } | 2385 | } |
2370 | 2386 | ||
@@ -2478,9 +2494,12 @@ namespace OpenSim.Region.Environment.Scenes | |||
2478 | /// <param name="modal"></param> | 2494 | /// <param name="modal"></param> |
2479 | public void SendAlertToUser(LLUUID agentID, string message, bool modal) | 2495 | public void SendAlertToUser(LLUUID agentID, string message, bool modal) |
2480 | { | 2496 | { |
2481 | if (m_scenePresences.ContainsKey(agentID)) | 2497 | lock (m_scenePresences) |
2482 | { | 2498 | { |
2483 | m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage(message, modal); | 2499 | if (m_scenePresences.ContainsKey(agentID)) |
2500 | { | ||
2501 | m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage(message, modal); | ||
2502 | } | ||
2484 | } | 2503 | } |
2485 | } | 2504 | } |
2486 | 2505 | ||
@@ -2494,28 +2513,31 @@ namespace OpenSim.Region.Environment.Scenes | |||
2494 | public void handleRequestGodlikePowers(LLUUID agentID, LLUUID sessionID, LLUUID token, bool godLike, | 2513 | public void handleRequestGodlikePowers(LLUUID agentID, LLUUID sessionID, LLUUID token, bool godLike, |
2495 | IClientAPI controllingClient) | 2514 | IClientAPI controllingClient) |
2496 | { | 2515 | { |
2497 | // First check that this is the sim owner | 2516 | lock (m_scenePresences) |
2498 | if (Permissions.GenericEstatePermission(agentID)) | ||
2499 | { | 2517 | { |
2500 | // User needs to be logged into this sim | 2518 | // User needs to be logged into this sim |
2501 | if (m_scenePresences.ContainsKey(agentID)) | 2519 | if (m_scenePresences.ContainsKey(agentID)) |
2502 | { | 2520 | { |
2503 | // Next we check for spoofing..... | 2521 | // First check that this is the sim owner |
2504 | LLUUID testSessionID = m_scenePresences[agentID].ControllingClient.SessionId; | 2522 | if (Permissions.GenericEstatePermission(agentID)) |
2505 | if (sessionID == testSessionID) | ||
2506 | { | 2523 | { |
2507 | if (sessionID == controllingClient.SessionId) | 2524 | // Next we check for spoofing..... |
2525 | LLUUID testSessionID = m_scenePresences[agentID].ControllingClient.SessionId; | ||
2526 | if (sessionID == testSessionID) | ||
2508 | { | 2527 | { |
2509 | //m_log.Info("godlike: " + godLike.ToString()); | 2528 | if (sessionID == controllingClient.SessionId) |
2510 | m_scenePresences[agentID].GrantGodlikePowers(agentID, testSessionID, token, godLike); | 2529 | { |
2530 | //m_log.Info("godlike: " + godLike.ToString()); | ||
2531 | m_scenePresences[agentID].GrantGodlikePowers(agentID, testSessionID, token, godLike); | ||
2532 | } | ||
2511 | } | 2533 | } |
2512 | } | 2534 | } |
2535 | else | ||
2536 | { | ||
2537 | m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage("Request for god powers denied", false); | ||
2538 | } | ||
2513 | } | 2539 | } |
2514 | } | 2540 | } |
2515 | else | ||
2516 | { | ||
2517 | m_scenePresences[agentID].ControllingClient.SendAgentAlertMessage("Request for god powers denied", false); | ||
2518 | } | ||
2519 | } | 2541 | } |
2520 | 2542 | ||
2521 | /// <summary> | 2543 | /// <summary> |
@@ -2571,55 +2593,59 @@ namespace OpenSim.Region.Environment.Scenes | |||
2571 | { | 2593 | { |
2572 | // For some reason the client sends this seemingly hard coded UUID for kicking everyone. Dun-know. | 2594 | // For some reason the client sends this seemingly hard coded UUID for kicking everyone. Dun-know. |
2573 | LLUUID kickUserID = new LLUUID("44e87126e7944ded05b37c42da3d5cdb"); | 2595 | LLUUID kickUserID = new LLUUID("44e87126e7944ded05b37c42da3d5cdb"); |
2574 | if (m_scenePresences.ContainsKey(agentID) || agentID == kickUserID) | 2596 | lock (m_scenePresences) |
2575 | { | 2597 | { |
2576 | if (Permissions.GenericEstatePermission(godID)) | 2598 | if (m_scenePresences.ContainsKey(agentID) || agentID == kickUserID) |
2577 | { | 2599 | { |
2578 | if (agentID == kickUserID) | 2600 | if (Permissions.GenericEstatePermission(godID)) |
2579 | { | 2601 | { |
2580 | ClientManager.ForEachClient(delegate(IClientAPI controller) | 2602 | if (agentID == kickUserID) |
2581 | { | 2603 | { |
2582 | if (controller.AgentId != godID) | 2604 | ClientManager.ForEachClient(delegate(IClientAPI controller) |
2583 | controller.Kick(Helpers.FieldToUTF8String(reason)); | 2605 | { |
2606 | if (controller.AgentId != godID) | ||
2607 | controller.Kick(Helpers.FieldToUTF8String(reason)); | ||
2584 | 2608 | ||
2585 | 2609 | ||
2586 | 2610 | ||
2587 | } | 2611 | } |
2588 | ); | 2612 | ); |
2589 | // This is a bit crude. It seems the client will be null before it actually stops the thread | 2613 | |
2590 | // The thread will kill itself eventually :/ | 2614 | // This is a bit crude. It seems the client will be null before it actually stops the thread |
2591 | // Is there another way to make sure *all* clients get this 'inter region' message? | 2615 | // The thread will kill itself eventually :/ |
2592 | ClientManager.ForEachClient(delegate(IClientAPI controller) | 2616 | // Is there another way to make sure *all* clients get this 'inter region' message? |
2593 | { | 2617 | ClientManager.ForEachClient(delegate(IClientAPI controller) |
2594 | ScenePresence p = GetScenePresence(controller.AgentId); | ||
2595 | bool childagent = !p.Equals(null) && p.IsChildAgent; | ||
2596 | if (controller.AgentId != godID && !childagent) | ||
2597 | // Do we really want to kick the initiator of this madness? | ||
2598 | { | 2618 | { |
2599 | controller.Close(true); | 2619 | ScenePresence p = GetScenePresence(controller.AgentId); |
2620 | bool childagent = !p.Equals(null) && p.IsChildAgent; | ||
2621 | if (controller.AgentId != godID && !childagent) | ||
2622 | // Do we really want to kick the initiator of this madness? | ||
2623 | { | ||
2624 | controller.Close(true); | ||
2625 | } | ||
2600 | } | 2626 | } |
2601 | } | 2627 | ); |
2602 | ); | ||
2603 | } | ||
2604 | else | ||
2605 | { | ||
2606 | if (m_scenePresences[agentID].IsChildAgent) | ||
2607 | { | ||
2608 | m_innerScene.removeUserCount(false); | ||
2609 | } | 2628 | } |
2610 | else | 2629 | else |
2611 | { | 2630 | { |
2612 | m_innerScene.removeUserCount(true); | 2631 | if (m_scenePresences[agentID].IsChildAgent) |
2613 | } | 2632 | { |
2633 | m_innerScene.removeUserCount(false); | ||
2634 | } | ||
2635 | else | ||
2636 | { | ||
2637 | m_innerScene.removeUserCount(true); | ||
2638 | } | ||
2614 | 2639 | ||
2615 | m_scenePresences[agentID].ControllingClient.Kick(Helpers.FieldToUTF8String(reason)); | 2640 | m_scenePresences[agentID].ControllingClient.Kick(Helpers.FieldToUTF8String(reason)); |
2616 | m_scenePresences[agentID].ControllingClient.Close(true); | 2641 | m_scenePresences[agentID].ControllingClient.Close(true); |
2642 | } | ||
2643 | } | ||
2644 | else | ||
2645 | { | ||
2646 | if (m_scenePresences.ContainsKey(godID)) | ||
2647 | m_scenePresences[godID].ControllingClient.SendAgentAlertMessage("Kick request denied", false); | ||
2617 | } | 2648 | } |
2618 | } | ||
2619 | else | ||
2620 | { | ||
2621 | if (m_scenePresences.ContainsKey(godID)) | ||
2622 | m_scenePresences[godID].ControllingClient.SendAgentAlertMessage("Kick request denied", false); | ||
2623 | } | 2649 | } |
2624 | } | 2650 | } |
2625 | } | 2651 | } |
diff --git a/OpenSim/Region/Environment/Scenes/ScenePresence.cs b/OpenSim/Region/Environment/Scenes/ScenePresence.cs index 052b85a..3554289 100644 --- a/OpenSim/Region/Environment/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Environment/Scenes/ScenePresence.cs | |||
@@ -1506,6 +1506,7 @@ namespace OpenSim.Region.Environment.Scenes | |||
1506 | foreach (ScenePresence avatar in avatars) | 1506 | foreach (ScenePresence avatar in avatars) |
1507 | { | 1507 | { |
1508 | SendFullUpdateToOtherClient(avatar); | 1508 | SendFullUpdateToOtherClient(avatar); |
1509 | |||
1509 | if (avatar.LocalId != LocalId) | 1510 | if (avatar.LocalId != LocalId) |
1510 | { | 1511 | { |
1511 | if (!avatar.m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) | 1512 | if (!avatar.m_isChildAgent || m_scene.m_seeIntoRegionFromNeighbor) |