aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Framework/TaskInventoryDictionary.cs
diff options
context:
space:
mode:
authoronefang2019-05-19 21:24:15 +1000
committeronefang2019-05-19 21:24:15 +1000
commit5e4d6cab00cb29cd088ab7b62ab13aff103b64cb (patch)
treea9fbc62df9eb2d1d9ba2698d8552eae71eca20d8 /OpenSim/Framework/TaskInventoryDictionary.cs
parentAdd a build script. (diff)
downloadopensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.zip
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.gz
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.bz2
opensim-SC_OLD-5e4d6cab00cb29cd088ab7b62ab13aff103b64cb.tar.xz
Dump OpenSim 0.9.0.1 into it's own branch.
Diffstat (limited to 'OpenSim/Framework/TaskInventoryDictionary.cs')
-rw-r--r--OpenSim/Framework/TaskInventoryDictionary.cs196
1 files changed, 190 insertions, 6 deletions
diff --git a/OpenSim/Framework/TaskInventoryDictionary.cs b/OpenSim/Framework/TaskInventoryDictionary.cs
index 8af2c41..223d91f 100644
--- a/OpenSim/Framework/TaskInventoryDictionary.cs
+++ b/OpenSim/Framework/TaskInventoryDictionary.cs
@@ -27,9 +27,13 @@
27 27
28using System; 28using System;
29using System.Collections.Generic; 29using System.Collections.Generic;
30using System.Threading;
31using System.Reflection;
30using System.Xml; 32using System.Xml;
33using System.Diagnostics;
31using System.Xml.Schema; 34using System.Xml.Schema;
32using System.Xml.Serialization; 35using System.Xml.Serialization;
36using log4net;
33using OpenMetaverse; 37using OpenMetaverse;
34 38
35namespace OpenSim.Framework 39namespace OpenSim.Framework
@@ -47,6 +51,187 @@ namespace OpenSim.Framework
47 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType); 51 // private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
48 52
49 private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem)); 53 private static XmlSerializer tiiSerializer = new XmlSerializer(typeof (TaskInventoryItem));
54 private static readonly ILog m_log = LogManager.GetLogger(MethodBase.GetCurrentMethod().DeclaringType);
55
56 private Thread LockedByThread;
57// private string WriterStack;
58
59// private Dictionary<Thread, string> ReadLockers =
60// new Dictionary<Thread, string>();
61
62 /// <value>
63 /// An advanced lock for inventory data
64 /// </value>
65 private volatile System.Threading.ReaderWriterLockSlim m_itemLock = new System.Threading.ReaderWriterLockSlim();
66
67
68 ~TaskInventoryDictionary()
69 {
70 m_itemLock.Dispose();
71 m_itemLock = null;
72 }
73
74 /// <summary>
75 /// Are we readlocked by the calling thread?
76 /// </summary>
77 public bool IsReadLockedByMe()
78 {
79 if (m_itemLock.RecursiveReadCount > 0)
80 {
81 return true;
82 }
83 else
84 {
85 return false;
86 }
87 }
88
89 /// <summary>
90 /// Lock our inventory list for reading (many can read, one can write)
91 /// </summary>
92 public void LockItemsForRead(bool locked)
93 {
94 if (locked)
95 {
96 if (m_itemLock.IsWriteLockHeld && LockedByThread != null)
97 {
98 if (!LockedByThread.IsAlive)
99 {
100 //Locked by dead thread, reset.
101 m_itemLock = new System.Threading.ReaderWriterLockSlim();
102 }
103 }
104
105 if (m_itemLock.RecursiveReadCount > 0)
106 {
107 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.");
108 try
109 {
110 // That call stack is useful for end users only. RealProgrammers need a full dump. Commented.
111 // StackTrace stackTrace = new StackTrace(); // get call stack
112 // StackFrame[] stackFrames = stackTrace.GetFrames(); // get method calls (frames)
113 //
114 // // write call stack method names
115 // foreach (StackFrame stackFrame in stackFrames)
116 // {
117 // m_log.Error("[SceneObjectGroup.m_parts] "+(stackFrame.GetMethod().Name)); // write method name
118 // }
119
120 // The below is far more useful
121// System.Console.WriteLine("------------------------------------------");
122// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
123// System.Console.WriteLine("------------------------------------------");
124// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
125// {
126// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
127// System.Console.WriteLine("------------------------------------------");
128// }
129 }
130 catch
131 {}
132 m_itemLock.ExitReadLock();
133 }
134 if (m_itemLock.RecursiveWriteCount > 0)
135 {
136 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
137// try
138// {
139// System.Console.WriteLine("------------------------------------------");
140// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
141// System.Console.WriteLine("------------------------------------------");
142// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
143// System.Console.WriteLine("------------------------------------------");
144// }
145// catch
146// {}
147 m_itemLock.ExitWriteLock();
148 }
149
150 while (!m_itemLock.TryEnterReadLock(60000))
151 {
152 m_log.Error("Thread lock detected while trying to aquire READ 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.");
153 //if (m_itemLock.IsWriteLockHeld)
154 //{
155 m_itemLock = new System.Threading.ReaderWriterLockSlim();
156// System.Console.WriteLine("------------------------------------------");
157// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
158// System.Console.WriteLine("------------------------------------------");
159// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
160// System.Console.WriteLine("------------------------------------------");
161// LockedByThread = null;
162// ReadLockers.Clear();
163 //}
164 }
165// ReadLockers[Thread.CurrentThread] = Environment.StackTrace;
166 }
167 else
168 {
169 if (m_itemLock.RecursiveReadCount>0)
170 {
171 m_itemLock.ExitReadLock();
172 }
173// if (m_itemLock.RecursiveReadCount == 0)
174// ReadLockers.Remove(Thread.CurrentThread);
175 }
176 }
177
178 /// <summary>
179 /// Lock our inventory list for writing (many can read, one can write)
180 /// </summary>
181 public void LockItemsForWrite(bool locked)
182 {
183 if (locked)
184 {
185 //Enter a write lock, wait indefinately for one to open.
186 if (m_itemLock.RecursiveReadCount > 0)
187 {
188 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.");
189 m_itemLock.ExitReadLock();
190 }
191 if (m_itemLock.RecursiveWriteCount > 0)
192 {
193 m_log.Error("[TaskInventoryDictionary] Recursive write lock requested. This should not happen and means something needs to be fixed.");
194
195 m_itemLock.ExitWriteLock();
196 }
197 while (!m_itemLock.TryEnterWriteLock(60000))
198 {
199 if (m_itemLock.IsWriteLockHeld)
200 {
201 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.");
202// System.Console.WriteLine("------------------------------------------");
203// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
204// System.Console.WriteLine("------------------------------------------");
205// System.Console.WriteLine("Locker's call stack:\n" + WriterStack);
206// System.Console.WriteLine("------------------------------------------");
207 }
208 else
209 {
210 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.");
211// System.Console.WriteLine("------------------------------------------");
212// System.Console.WriteLine("My call stack:\n" + Environment.StackTrace);
213// System.Console.WriteLine("------------------------------------------");
214// foreach (KeyValuePair<Thread, string> kvp in ReadLockers)
215// {
216// System.Console.WriteLine("Locker name {0} call stack:\n" + kvp.Value, kvp.Key.Name);
217// System.Console.WriteLine("------------------------------------------");
218// }
219 }
220 m_itemLock = new System.Threading.ReaderWriterLockSlim();
221// ReadLockers.Clear();
222 }
223
224 LockedByThread = Thread.CurrentThread;
225// WriterStack = Environment.StackTrace;
226 }
227 else
228 {
229 if (m_itemLock.RecursiveWriteCount > 0)
230 {
231 m_itemLock.ExitWriteLock();
232 }
233 }
234 }
50 235
51 #region ICloneable Members 236 #region ICloneable Members
52 237
@@ -54,14 +239,13 @@ namespace OpenSim.Framework
54 { 239 {
55 TaskInventoryDictionary clone = new TaskInventoryDictionary(); 240 TaskInventoryDictionary clone = new TaskInventoryDictionary();
56 241
57 lock (this) 242 m_itemLock.EnterReadLock();
243 foreach (UUID uuid in Keys)
58 { 244 {
59 foreach (UUID uuid in Keys) 245 clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
60 {
61 clone.Add(uuid, (TaskInventoryItem) this[uuid].Clone());
62 }
63 } 246 }
64 247 m_itemLock.ExitReadLock();
248
65 return clone; 249 return clone;
66 } 250 }
67 251