From 03993d0b14599358ac30a001cebd5b2145881c65 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Nov 2011 18:12:12 +0000 Subject: Fix race condition that would sometimes send or save appearance for the wrong avatar. In AvatarFactoryModule.HandleAppearanceUpdateTimer(), we loop through appearance save and send requests and dispatch via a FireAndForget thread. If there was more than one request in the save or send queue, then this led to a subtle race condition where the foreach loop would load in the next KeyValuePair before the thread was dispatched. This gave the thread the wrong avatar ID, leaving some avatar appearance cloudy since appearance data was never sent. This change loads the fields into local references so that this doesn't happen. --- .../Avatar/AvatarFactory/AvatarFactoryModule.cs | 28 ++++++++++++++++------ 1 file changed, 21 insertions(+), 7 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs index 236a47c..07d1cb3 100644 --- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs +++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs @@ -169,6 +169,8 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory public bool SendAppearance(UUID agentId) { +// m_log.DebugFormat("[AVFACTORY]: Sending appearance for {0}", agentId); + ScenePresence sp = m_scene.GetScenePresence(agentId); if (sp == null) { @@ -257,7 +259,7 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory /// public void QueueAppearanceSend(UUID agentid) { - // m_log.WarnFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); +// m_log.DebugFormat("[AVFACTORY]: Queue appearance send for {0}", agentid); // 10000 ticks per millisecond, 1000 milliseconds per second long timestamp = DateTime.Now.Ticks + Convert.ToInt64(m_sendtime * 1000 * 10000); @@ -393,10 +395,17 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory Dictionary sends = new Dictionary(m_sendqueue); foreach (KeyValuePair kvp in sends) { - if (kvp.Value < now) + // We have to load the key and value into local parameters to avoid a race condition if we loop + // around and load kvp with a different value before FireAndForget has launched its thread. + UUID avatarID = kvp.Key; + long sendTime = kvp.Value; + +// m_log.DebugFormat("[AVFACTORY]: Handling queued appearance updates for {0}, update delta to now is {1}", avatarID, sendTime - now); + + if (sendTime < now) { - Util.FireAndForget(delegate(object o) { SendAppearance(kvp.Key); }); - m_sendqueue.Remove(kvp.Key); + Util.FireAndForget(o => SendAppearance(avatarID)); + m_sendqueue.Remove(avatarID); } } } @@ -406,10 +415,15 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory Dictionary saves = new Dictionary(m_savequeue); foreach (KeyValuePair kvp in saves) { - if (kvp.Value < now) + // We have to load the key and value into local parameters to avoid a race condition if we loop + // around and load kvp with a different value before FireAndForget has launched its thread. + UUID avatarID = kvp.Key; + long sendTime = kvp.Value; + + if (sendTime < now) { - Util.FireAndForget(delegate(object o) { SaveAppearance(kvp.Key); }); - m_savequeue.Remove(kvp.Key); + Util.FireAndForget(o => SaveAppearance(avatarID)); + m_savequeue.Remove(avatarID); } } } -- cgit v1.1 From 72923134e9ab9ab946253c883d40536af389ab18 Mon Sep 17 00:00:00 2001 From: Justin Clark-Casey (justincc) Date: Wed, 2 Nov 2011 18:40:49 +0000 Subject: Get some hopefully more useful exception information when OpenJPEG.EncodeFromImage() fails in VectorRender and DynamicTexture modules --- .../CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs | 6 ++++-- .../CoreModules/Scripting/VectorRender/VectorRenderModule.cs | 7 ++++--- 2 files changed, 8 insertions(+), 5 deletions(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs index 6075e19..f2c8b3d 100644 --- a/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/DynamicTexture/DynamicTextureModule.cs @@ -395,9 +395,11 @@ namespace OpenSim.Region.CoreModules.Scripting.DynamicTexture { result = OpenJPEG.EncodeFromImage(joint, true); } - catch (Exception) + catch (Exception e) { - m_log.Error("[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Empty byte data returned!"); + m_log.ErrorFormat( + "[DYNAMICTEXTUREMODULE]: OpenJpeg Encode Failed. Exception {0}{1}", + e.Message, e.StackTrace); } return result; diff --git a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs index 7316e5b..c061868 100644 --- a/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs +++ b/OpenSim/Region/CoreModules/Scripting/VectorRender/VectorRenderModule.cs @@ -338,10 +338,11 @@ namespace OpenSim.Region.CoreModules.Scripting.VectorRender { imageJ2000 = OpenJPEG.EncodeFromImage(bitmap, true); } - catch (Exception) + catch (Exception e) { - m_log.Error( - "[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Empty byte data returned!"); + m_log.ErrorFormat( + "[VECTORRENDERMODULE]: OpenJpeg Encode Failed. Exception {0}{1}", + e.Message, e.StackTrace); } m_textureManager.ReturnData(id, imageJ2000); -- cgit v1.1 From e2c51a977d42822fe78ae0744117afb7bf509d35 Mon Sep 17 00:00:00 2001 From: Dan Lake Date: Wed, 2 Nov 2011 14:59:00 -0700 Subject: Changes UpdateFlag in SOP to an enumeration of NONE, TERSE and FULL. UpdateFlag is now referenced/used only within SOP and SOG. Outsiders are using ScheduleFullUpdate, ScheduleTerseUpdate or ClearUpdateSchedule on SOP consistently now. Also started working toward eliminating those calls to ScheduleFullUpdate, ScheduleTerseUpdate or ClearUpdateSchedule from outside SOP in favor of just setting properties on SOP and let SOP decide if an update should be scheduled. This consolidates the update policy within SOP and the client rather than everywhere that makes changes to SOP. Some places forget to call update while others call it multiple times, "just to be sure". UpdateFlag and Schedule*Update will both be made private shortly. UpdateFlag is intended to be transient and internal to SOP so it has been removed from XML serializer for SOPs. --- .../Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'OpenSim/Region/CoreModules') diff --git a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs index 7324b26..7251bd8 100644 --- a/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs +++ b/OpenSim/Region/CoreModules/Framework/EntityTransfer/EntityTransferModule.cs @@ -1714,7 +1714,7 @@ namespace OpenSim.Region.CoreModules.Framework.EntityTransfer //m_log.Debug(" >>> CrossPrimGroupIntoNewRegion <<<"); bool successYN = false; - grp.RootPart.UpdateFlag = 0; + grp.RootPart.ClearUpdateSchedule(); //int primcrossingXMLmethod = 0; if (destination != null) -- cgit v1.1