From e8fbeeba5f2c02bf89ade1d8c0fa135d065096e7 Mon Sep 17 00:00:00 2001
From: Justin Clark-Casey (justincc)
Date: Mon, 19 Dec 2011 19:08:24 +0000
Subject: Fix race condition where the appearance update timer could be stopped
 just after another thread had started it on QueueAppearanceSave() or *Send()

However, the window for this race is very small, and the next queued appearance save or send would restart the timer anyway.
---
 .../CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs      | 9 ++++++---
 1 file changed, 6 insertions(+), 3 deletions(-)

diff --git a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
index f1a81ae..e8aee3e 100644
--- a/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
+++ b/OpenSim/Region/CoreModules/Avatar/AvatarFactory/AvatarFactoryModule.cs
@@ -417,10 +417,13 @@ namespace OpenSim.Region.CoreModules.Avatar.AvatarFactory
                         m_savequeue.Remove(avatarID);
                     }
                 }
-            }
 
-            if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
-                m_updateTimer.Stop();
+                // We must lock both queues here so that QueueAppearanceSave() or *Send() don't m_updateTimer.Start() on
+                // another thread inbetween the first count calls and m_updateTimer.Stop() on this thread.
+                lock (m_sendqueue)
+                    if (m_savequeue.Count == 0 && m_sendqueue.Count == 0)
+                        m_updateTimer.Stop();
+            }
         }
 
         private void SaveAppearance(UUID agentid)
-- 
cgit v1.1