aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Environment/Modules/Avatar
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs56
1 files changed, 35 insertions, 21 deletions
diff --git a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs
index 7b358c2..28ed991 100644
--- a/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs
+++ b/OpenSim/Region/Environment/Modules/Avatar/InstantMessage/PresenceModule.cs
@@ -58,20 +58,25 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
58 58
59 public void Initialise(Scene scene, IConfigSource config) 59 public void Initialise(Scene scene, IConfigSource config)
60 { 60 {
61 IConfig cnf = config.Configs["Messaging"]; 61 lock (m_Scenes)
62 if (cnf != null && cnf.GetString( 62 {
63 "PresenceModule", "PresenceModule") != 63 // This is a shared module; Initialise will be called for every region on this server.
64 "PresenceModule") 64 // Only check config once for the first region.
65 return; 65 if (m_Scenes.Count == 0)
66 {
67 IConfig cnf = config.Configs["Messaging"];
68 if (cnf != null && cnf.GetString(
69 "PresenceModule", "PresenceModule") !=
70 "PresenceModule")
71 return;
66 72
67 cnf = config.Configs["Startup"]; 73 cnf = config.Configs["Startup"];
68 if (cnf != null) 74 if (cnf != null)
69 m_Gridmode = cnf.GetBoolean("gridmode", false); 75 m_Gridmode = cnf.GetBoolean("gridmode", false);
70 76
71 m_Enabled = true; 77 m_Enabled = true;
78 }
72 79
73 lock (m_Scenes)
74 {
75 if (m_Gridmode) 80 if (m_Gridmode)
76 NotifyMessageServerOfStartup(scene); 81 NotifyMessageServerOfStartup(scene);
77 82
@@ -122,27 +127,36 @@ namespace OpenSim.Region.Environment.Modules.Avatar.InstantMessage
122 if (!(client.Scene is Scene)) 127 if (!(client.Scene is Scene))
123 return; 128 return;
124 129
125 if (!(m_RootAgents.ContainsKey(client.AgentId)))
126 return;
127
128 Scene scene = (Scene)client.Scene; 130 Scene scene = (Scene)client.Scene;
129 131
130 if (m_RootAgents[client.AgentId] != scene) 132 // OnConnectionClosed can be called from several threads at once (with different client, of course)
131 return; 133 // Concurrent access to m_RootAgents is prone to failure on multi-core/-processor systems without
132 134 // correct locking).
133 m_RootAgents.Remove(client.AgentId); 135 lock (m_RootAgents)
136 {
137 Scene rootScene;
138 if (!(m_RootAgents.TryGetValue(client.AgentId, out rootScene)) || scene != rootScene)
139 return;
134 140
141 m_RootAgents.Remove(client.AgentId);
142 }
135 NotifyMessageServerOfAgentLeaving(client.AgentId, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); 143 NotifyMessageServerOfAgentLeaving(client.AgentId, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle);
136 } 144 }
137 145
138 public void OnSetRootAgentScene(UUID agentID, Scene scene) 146 public void OnSetRootAgentScene(UUID agentID, Scene scene)
139 { 147 {
140 if (m_RootAgents.ContainsKey(agentID)) 148 // OnSetRootAgentScene can be called from several threads at once (with different agentID).
149 // Concurrent access to m_RootAgents is prone to failure on multi-core/-processor systems without
150 // correct locking).
151 lock (m_RootAgents)
141 { 152 {
142 if (m_RootAgents[agentID] == scene) 153 Scene rootScene;
154 if (m_RootAgents.TryGetValue(agentID, out rootScene) && scene == rootScene)
155 {
143 return; 156 return;
157 }
158 m_RootAgents[agentID] = scene;
144 } 159 }
145 m_RootAgents[agentID] = scene;
146 NotifyMessageServerOfAgentLocation(agentID, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle); 160 NotifyMessageServerOfAgentLocation(agentID, scene.RegionInfo.RegionID, scene.RegionInfo.RegionHandle);
147 } 161 }
148 162