diff options
Diffstat (limited to '')
-rw-r--r-- | OpenSim/Framework/TaskInventoryDictionary.cs | 49 |
1 files changed, 47 insertions, 2 deletions
diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs index 4b9a509..814758a 100644 --- a/OpenSim/Framework/TaskInventoryDictionary.cs +++ b/OpenSim/Framework/TaskInventoryDictionary.cs | |||
@@ -30,6 +30,7 @@ using System.Collections.Generic; | |||
30 | using System.Threading; | 30 | using System.Threading; |
31 | using System.Reflection; | 31 | using System.Reflection; |
32 | using System.Xml; | 32 | using System.Xml; |
33 | using System.Diagnostics; | ||
33 | using System.Xml.Schema; | 34 | using System.Xml.Schema; |
34 | using System.Xml.Serialization; | 35 | using System.Xml.Serialization; |
35 | using log4net; | 36 | using log4net; |
@@ -51,6 +52,11 @@ namespace OpenSim.Framework | |||
51 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); | 52 | private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); |
52 | 53 | ||
53 | private Thread LockedByThread; | 54 | private Thread LockedByThread; |
55 | private string WriterStack; | ||
56 | |||
57 | private Dictionary<Thread, string> ReadLockers = | ||
58 | new Dictionary<Thread, string>(); | ||
59 | |||
54 | /// <value> | 60 | /// <value> |
55 | /// An advanced lock for inventory data | 61 | /// An advanced lock for inventory data |
56 | /// </value> | 62 | /// </value> |
@@ -90,6 +96,19 @@ namespace OpenSim.Framework | |||
90 | if (m_itemLock.RecursiveReadCount > 0) | 96 | if (m_itemLock.RecursiveReadCount > 0) |
91 | { | 97 | { |
92 | m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); | 98 | m_log.Error("[TaskInventoryDictionary] Recursive read lock requested. This should not happen and means something needs to be fixed. For now though, it's safe to continue."); |
99 | try | ||
100 | { | ||
101 | StackTrace stackTrace = new StackTrace(); // get call stack | ||
102 | StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames) | ||
103 | |||
104 | // write call stack method names | ||
105 | foreach (StackFrame stackFrame in stackFrames) | ||
106 | { | ||
107 | m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name | ||
108 | } | ||
109 | } | ||
110 | catch | ||
111 | {} | ||
93 | m_itemLock.ExitReadLock(); | 112 | m_itemLock.ExitReadLock(); |
94 | } | 113 | } |
95 | if (m_itemLock.RecursiveWriteCount > 0) | 114 | if (m_itemLock.RecursiveWriteCount > 0) |
@@ -104,6 +123,13 @@ namespace OpenSim.Framework | |||
104 | if (m_itemLock.IsWriteLockHeld) | 123 | if (m_itemLock.IsWriteLockHeld) |
105 | { | 124 | { |
106 | m_itemLock = new System.Threading.ReaderWriterLockSlim(); | 125 | m_itemLock = new System.Threading.ReaderWriterLockSlim(); |
126 | System.Console.WriteLine("------------------------------------------"); | ||
127 | System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); | ||
128 | System.Console.WriteLine("------------------------------------------"); | ||
129 | System.Console.WriteLine("Locker's call stack:\n" + WriterStack); | ||
130 | System.Console.WriteLine("------------------------------------------"); | ||
131 | LockedByThread = null; | ||
132 | ReadLockers.Clear(); | ||
107 | } | 133 | } |
108 | } | 134 | } |
109 | } | 135 | } |
@@ -136,14 +162,33 @@ namespace OpenSim.Framework | |||
136 | } | 162 | } |
137 | while (!m_itemLock.TryEnterWriteLock(60000)) | 163 | while (!m_itemLock.TryEnterWriteLock(60000)) |
138 | { | 164 | { |
139 | m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
140 | if (m_itemLock.IsWriteLockHeld) | 165 | if (m_itemLock.IsWriteLockHeld) |
141 | { | 166 | { |
142 | m_itemLock = new System.Threading.ReaderWriterLockSlim(); | 167 | m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by thread " + LockedByThread.Name + ". I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); |
168 | System.Console.WriteLine("------------------------------------------"); | ||
169 | System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); | ||
170 | System.Console.WriteLine("------------------------------------------"); | ||
171 | System.Console.WriteLine("Locker's call stack:\n" + WriterStack); | ||
172 | System.Console.WriteLine("------------------------------------------"); | ||
173 | } | ||
174 | else | ||
175 | { | ||
176 | m_log.Error("Thread lock detected while trying to aquire WRITE lock in TaskInventoryDictionary. Locked by a reader. I'm going to try to solve the thread lock automatically to preserve region stability, but this needs to be fixed."); | ||
177 | System.Console.WriteLine("------------------------------------------"); | ||
178 | System.Console.WriteLine("My call stack:\n" + Environment.StackTrace); | ||
179 | System.Console.WriteLine("------------------------------------------"); | ||
180 | foreach (KeyValuePair<Thread, string> kvp in ReadLockers) | ||
181 | { | ||
182 | System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name); | ||
183 | System.Console.WriteLine("------------------------------------------"); | ||
184 | } | ||
143 | } | 185 | } |
186 | m_itemLock = new System.Threading.ReaderWriterLockSlim(); | ||
187 | ReadLockers.Clear(); | ||
144 | } | 188 | } |
145 | 189 | ||
146 | LockedByThread = Thread.CurrentThread; | 190 | LockedByThread = Thread.CurrentThread; |
191 | WriterStack = Environment.StackTrace; | ||
147 | } | 192 | } |
148 | else | 193 | else |
149 | { | 194 | { |