diff options
Diffstat (limited to 'OpenSim')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 44 |
1 files changed, 30 insertions, 14 deletions
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 0cc00ed..84201cc 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1190,22 +1190,36 @@ namespace OpenSim.Region.Framework.Scenes | |||
1190 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | 1190 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently |
1191 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | 1191 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are |
1192 | // not transporting the required data. | 1192 | // not transporting the required data. |
1193 | lock (m_attachments) | 1193 | // |
1194 | // We need to restart scripts here so that they receive the correct changed events (CHANGED_TELEPORT | ||
1195 | // and CHANGED_REGION) when the attachments have been rezzed in the new region. This cannot currently | ||
1196 | // be done in AttachmentsModule.CopyAttachments(AgentData ad, IScenePresence sp) itself since we are | ||
1197 | // not transporting the required data. | ||
1198 | // | ||
1199 | // We must take a copy of the attachments list here (rather than locking) to avoid a deadlock where a script in one of | ||
1200 | // the attachments may start processing an event (which locks ScriptInstance.m_Script) that then calls a method here | ||
1201 | // which needs to lock m_attachments. ResumeScripts() needs to take a ScriptInstance.m_Script lock to try to unset the Suspend status. | ||
1202 | // | ||
1203 | // FIXME: In theory, this deadlock should not arise since scripts should not be processing events until ResumeScripts(). | ||
1204 | // But XEngine starts all scripts unsuspended. Starting them suspended will not currently work because script rezzing | ||
1205 | // is placed in an asynchronous queue in XEngine and so the ResumeScripts() call will almost certainly execute before the | ||
1206 | // script is rezzed. This means the ResumeScripts() does absolutely nothing when using XEngine. | ||
1207 | // | ||
1208 | // One cannot simply iterate over attachments in a fire and forget thread because this would no longer | ||
1209 | // be locked, allowing race conditions if other code changes the attachments list. | ||
1210 | List<SceneObjectGroup> attachments = GetAttachments(); | ||
1211 | |||
1212 | if (attachments.Count > 0) | ||
1194 | { | 1213 | { |
1195 | if (HasAttachments()) | 1214 | m_log.DebugFormat( |
1196 | { | 1215 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); |
1197 | m_log.DebugFormat( | ||
1198 | "[SCENE PRESENCE]: Restarting scripts in attachments for {0} in {1}", Name, Scene.Name); | ||
1199 | 1216 | ||
1200 | // Resume scripts | 1217 | // Resume scripts |
1201 | Util.FireAndForget(delegate(object x) { | 1218 | foreach (SceneObjectGroup sog in attachments) |
1202 | foreach (SceneObjectGroup sog in m_attachments) | 1219 | { |
1203 | { | 1220 | sog.ScheduleGroupForFullUpdate(); |
1204 | sog.ScheduleGroupForFullUpdate(); | 1221 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); |
1205 | sog.RootPart.ParentGroup.CreateScriptInstances(0, false, m_scene.DefaultScriptEngine, GetStateSource()); | 1222 | sog.ResumeScripts(); |
1206 | sog.ResumeScripts(); | ||
1207 | } | ||
1208 | }); | ||
1209 | } | 1223 | } |
1210 | } | 1224 | } |
1211 | } | 1225 | } |
@@ -3227,6 +3241,8 @@ namespace OpenSim.Region.Framework.Scenes | |||
3227 | // again here... this comes after the cached appearance check because the avatars | 3241 | // again here... this comes after the cached appearance check because the avatars |
3228 | // appearance goes into the avatar update packet | 3242 | // appearance goes into the avatar update packet |
3229 | SendAvatarDataToAllAgents(); | 3243 | SendAvatarDataToAllAgents(); |
3244 | |||
3245 | // This invocation always shows up in the viewer logs as an error. Is it needed? | ||
3230 | SendAppearanceToAgent(this); | 3246 | SendAppearanceToAgent(this); |
3231 | 3247 | ||
3232 | // If we are using the the cached appearance then send it out to everyone | 3248 | // If we are using the the cached appearance then send it out to everyone |