diff options
author | CasperW | 2009-11-24 18:02:12 +0100 |
---|---|---|
committer | CasperW | 2009-11-24 18:02:12 +0100 |
commit | d1147136946daf14724183b3191119be44ff8b16 (patch) | |
tree | fd5c056348acdd0ea82f4c797d15bcae3336ee28 /OpenSim/Region/Framework | |
parent | Swap the locking of m_EventQueue and m_Script to ease locks on script invento... (diff) | |
download | opensim-SC_OLD-d1147136946daf14724183b3191119be44ff8b16.zip opensim-SC_OLD-d1147136946daf14724183b3191119be44ff8b16.tar.gz opensim-SC_OLD-d1147136946daf14724183b3191119be44ff8b16.tar.bz2 opensim-SC_OLD-d1147136946daf14724183b3191119be44ff8b16.tar.xz |
Drop all locking of part.TaskInventory in favour of a ReaderWriterLockSlim lock handler. This gives us:
- Faster prim inventory actions. Multiple threads can read at once.
- Fixes the known prim inventory thread locks
- In the event of a thread lock occurring, it will usually self heal after sixty seconds with an error message in the console
Diffstat (limited to 'OpenSim/Region/Framework')
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | 38 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | 390 | ||||
-rw-r--r-- | OpenSim/Region/Framework/Scenes/ScenePresence.cs | 16 |
3 files changed, 235 insertions, 209 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs index cdec135..bbece2f 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPart.cs | |||
@@ -389,12 +389,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
389 | } | 389 | } |
390 | 390 | ||
391 | /// <value> | 391 | /// <value> |
392 | /// Access should be via Inventory directly - this property temporarily remains for xml serialization purposes | 392 | /// Get the inventory list |
393 | /// </value> | 393 | /// </value> |
394 | public TaskInventoryDictionary TaskInventory | 394 | public TaskInventoryDictionary TaskInventory |
395 | { | 395 | { |
396 | get { return m_inventory.Items; } | 396 | get { |
397 | set { m_inventory.Items = value; } | 397 | return m_inventory.Items; |
398 | } | ||
399 | set { | ||
400 | m_inventory.Items = value; | ||
401 | } | ||
398 | } | 402 | } |
399 | 403 | ||
400 | public uint ObjectFlags | 404 | public uint ObjectFlags |
@@ -2101,17 +2105,18 @@ namespace OpenSim.Region.Framework.Scenes | |||
2101 | //Trys to fetch sound id from prim's inventory. | 2105 | //Trys to fetch sound id from prim's inventory. |
2102 | //Prim's inventory doesn't support non script items yet | 2106 | //Prim's inventory doesn't support non script items yet |
2103 | 2107 | ||
2104 | lock (TaskInventory) | 2108 | TaskInventory.LockItemsForRead(true); |
2109 | |||
2110 | foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) | ||
2105 | { | 2111 | { |
2106 | foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) | 2112 | if (item.Value.Name == sound) |
2107 | { | 2113 | { |
2108 | if (item.Value.Name == sound) | 2114 | soundID = item.Value.ItemID; |
2109 | { | 2115 | break; |
2110 | soundID = item.Value.ItemID; | ||
2111 | break; | ||
2112 | } | ||
2113 | } | 2116 | } |
2114 | } | 2117 | } |
2118 | |||
2119 | TaskInventory.LockItemsForRead(false); | ||
2115 | } | 2120 | } |
2116 | 2121 | ||
2117 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); | 2122 | List<ScenePresence> avatarts = m_parentGroup.Scene.GetAvatars(); |
@@ -2457,17 +2462,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
2457 | if (!UUID.TryParse(sound, out soundID)) | 2462 | if (!UUID.TryParse(sound, out soundID)) |
2458 | { | 2463 | { |
2459 | // search sound file from inventory | 2464 | // search sound file from inventory |
2460 | lock (TaskInventory) | 2465 | TaskInventory.LockItemsForRead(true); |
2466 | foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) | ||
2461 | { | 2467 | { |
2462 | foreach (KeyValuePair<UUID, TaskInventoryItem> item in TaskInventory) | 2468 | if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) |
2463 | { | 2469 | { |
2464 | if (item.Value.Name == sound && item.Value.Type == (int)AssetType.Sound) | 2470 | soundID = item.Value.ItemID; |
2465 | { | 2471 | break; |
2466 | soundID = item.Value.ItemID; | ||
2467 | break; | ||
2468 | } | ||
2469 | } | 2472 | } |
2470 | } | 2473 | } |
2474 | TaskInventory.LockItemsForRead(false); | ||
2471 | } | 2475 | } |
2472 | 2476 | ||
2473 | if (soundID == UUID.Zero) | 2477 | if (soundID == UUID.Zero) |
diff --git a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs index f4ca877..4dc709e 100644 --- a/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs +++ b/OpenSim/Region/Framework/Scenes/SceneObjectPartInventory.cs | |||
@@ -80,7 +80,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
80 | /// </value> | 80 | /// </value> |
81 | protected internal TaskInventoryDictionary Items | 81 | protected internal TaskInventoryDictionary Items |
82 | { | 82 | { |
83 | get { return m_items; } | 83 | get { |
84 | return m_items; | ||
85 | } | ||
84 | set | 86 | set |
85 | { | 87 | { |
86 | m_items = value; | 88 | m_items = value; |
@@ -116,22 +118,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
116 | /// <param name="linkNum">Link number for the part</param> | 118 | /// <param name="linkNum">Link number for the part</param> |
117 | public void ResetInventoryIDs() | 119 | public void ResetInventoryIDs() |
118 | { | 120 | { |
119 | lock (Items) | 121 | m_items.LockItemsForWrite(true); |
122 | |||
123 | if (0 == Items.Count) | ||
120 | { | 124 | { |
121 | if (0 == Items.Count) | 125 | m_items.LockItemsForWrite(false); |
122 | return; | 126 | return; |
127 | } | ||
123 | 128 | ||
124 | HasInventoryChanged = true; | 129 | HasInventoryChanged = true; |
125 | m_part.ParentGroup.HasGroupChanged = true; | 130 | m_part.ParentGroup.HasGroupChanged = true; |
126 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 131 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
127 | Items.Clear(); | 132 | Items.Clear(); |
128 | 133 | ||
129 | foreach (TaskInventoryItem item in items) | 134 | foreach (TaskInventoryItem item in items) |
130 | { | 135 | { |
131 | item.ResetIDs(m_part.UUID); | 136 | item.ResetIDs(m_part.UUID); |
132 | Items.Add(item.ItemID, item); | 137 | Items.Add(item.ItemID, item); |
133 | } | ||
134 | } | 138 | } |
139 | m_items.LockItemsForWrite(false); | ||
135 | } | 140 | } |
136 | 141 | ||
137 | /// <summary> | 142 | /// <summary> |
@@ -140,25 +145,25 @@ namespace OpenSim.Region.Framework.Scenes | |||
140 | /// <param name="ownerId"></param> | 145 | /// <param name="ownerId"></param> |
141 | public void ChangeInventoryOwner(UUID ownerId) | 146 | public void ChangeInventoryOwner(UUID ownerId) |
142 | { | 147 | { |
143 | lock (Items) | 148 | m_items.LockItemsForWrite(true); |
149 | if (0 == Items.Count) | ||
144 | { | 150 | { |
145 | if (0 == Items.Count) | 151 | m_items.LockItemsForWrite(false); |
146 | { | 152 | return; |
147 | return; | 153 | } |
148 | } | ||
149 | 154 | ||
150 | HasInventoryChanged = true; | 155 | HasInventoryChanged = true; |
151 | m_part.ParentGroup.HasGroupChanged = true; | 156 | m_part.ParentGroup.HasGroupChanged = true; |
152 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 157 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
153 | foreach (TaskInventoryItem item in items) | 158 | foreach (TaskInventoryItem item in items) |
159 | { | ||
160 | if (ownerId != item.OwnerID) | ||
154 | { | 161 | { |
155 | if (ownerId != item.OwnerID) | 162 | item.LastOwnerID = item.OwnerID; |
156 | { | 163 | item.OwnerID = ownerId; |
157 | item.LastOwnerID = item.OwnerID; | ||
158 | item.OwnerID = ownerId; | ||
159 | } | ||
160 | } | 164 | } |
161 | } | 165 | } |
166 | m_items.LockItemsForWrite(false); | ||
162 | } | 167 | } |
163 | 168 | ||
164 | /// <summary> | 169 | /// <summary> |
@@ -167,24 +172,24 @@ namespace OpenSim.Region.Framework.Scenes | |||
167 | /// <param name="groupID"></param> | 172 | /// <param name="groupID"></param> |
168 | public void ChangeInventoryGroup(UUID groupID) | 173 | public void ChangeInventoryGroup(UUID groupID) |
169 | { | 174 | { |
170 | lock (Items) | 175 | m_items.LockItemsForWrite(true); |
176 | if (0 == Items.Count) | ||
171 | { | 177 | { |
172 | if (0 == Items.Count) | 178 | m_items.LockItemsForWrite(false); |
173 | { | 179 | return; |
174 | return; | 180 | } |
175 | } | ||
176 | 181 | ||
177 | HasInventoryChanged = true; | 182 | HasInventoryChanged = true; |
178 | m_part.ParentGroup.HasGroupChanged = true; | 183 | m_part.ParentGroup.HasGroupChanged = true; |
179 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | 184 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); |
180 | foreach (TaskInventoryItem item in items) | 185 | foreach (TaskInventoryItem item in items) |
186 | { | ||
187 | if (groupID != item.GroupID) | ||
181 | { | 188 | { |
182 | if (groupID != item.GroupID) | 189 | item.GroupID = groupID; |
183 | { | ||
184 | item.GroupID = groupID; | ||
185 | } | ||
186 | } | 190 | } |
187 | } | 191 | } |
192 | m_items.LockItemsForWrite(false); | ||
188 | } | 193 | } |
189 | 194 | ||
190 | /// <summary> | 195 | /// <summary> |
@@ -192,14 +197,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
192 | /// </summary> | 197 | /// </summary> |
193 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) | 198 | public void CreateScriptInstances(int startParam, bool postOnRez, string engine, int stateSource) |
194 | { | 199 | { |
195 | lock (m_items) | 200 | Items.LockItemsForRead(true); |
201 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | ||
202 | Items.LockItemsForRead(false); | ||
203 | foreach (TaskInventoryItem item in items) | ||
196 | { | 204 | { |
197 | foreach (TaskInventoryItem item in Items.Values) | 205 | if ((int)InventoryType.LSL == item.InvType) |
198 | { | 206 | { |
199 | if ((int)InventoryType.LSL == item.InvType) | 207 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); |
200 | { | ||
201 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); | ||
202 | } | ||
203 | } | 208 | } |
204 | } | 209 | } |
205 | } | 210 | } |
@@ -209,17 +214,20 @@ namespace OpenSim.Region.Framework.Scenes | |||
209 | /// </summary> | 214 | /// </summary> |
210 | public void RemoveScriptInstances() | 215 | public void RemoveScriptInstances() |
211 | { | 216 | { |
212 | lock (Items) | 217 | Items.LockItemsForRead(true); |
218 | IList<TaskInventoryItem> items = new List<TaskInventoryItem>(Items.Values); | ||
219 | Items.LockItemsForRead(false); | ||
220 | |||
221 | foreach (TaskInventoryItem item in items) | ||
213 | { | 222 | { |
214 | foreach (TaskInventoryItem item in Items.Values) | 223 | if ((int)InventoryType.LSL == item.InvType) |
215 | { | 224 | { |
216 | if ((int)InventoryType.LSL == item.InvType) | 225 | RemoveScriptInstance(item.ItemID); |
217 | { | 226 | m_part.RemoveScriptEvents(item.ItemID); |
218 | RemoveScriptInstance(item.ItemID); | ||
219 | m_part.RemoveScriptEvents(item.ItemID); | ||
220 | } | ||
221 | } | 227 | } |
222 | } | 228 | } |
229 | |||
230 | |||
223 | } | 231 | } |
224 | 232 | ||
225 | /// <summary> | 233 | /// <summary> |
@@ -244,8 +252,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
244 | if (stateSource == 1 && // Prim crossing | 252 | if (stateSource == 1 && // Prim crossing |
245 | m_part.ParentGroup.Scene.m_trustBinaries) | 253 | m_part.ParentGroup.Scene.m_trustBinaries) |
246 | { | 254 | { |
255 | m_items.LockItemsForWrite(true); | ||
247 | m_items[item.ItemID].PermsMask = 0; | 256 | m_items[item.ItemID].PermsMask = 0; |
248 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 257 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
258 | m_items.LockItemsForWrite(false); | ||
249 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 259 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
250 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); | 260 | m_part.LocalId, item.ItemID, String.Empty, startParam, postOnRez, engine, stateSource); |
251 | m_part.ParentGroup.AddActiveScriptCount(1); | 261 | m_part.ParentGroup.AddActiveScriptCount(1); |
@@ -266,8 +276,10 @@ namespace OpenSim.Region.Framework.Scenes | |||
266 | { | 276 | { |
267 | if (m_part.ParentGroup.m_savedScriptState != null) | 277 | if (m_part.ParentGroup.m_savedScriptState != null) |
268 | RestoreSavedScriptState(item.OldItemID, item.ItemID); | 278 | RestoreSavedScriptState(item.OldItemID, item.ItemID); |
279 | m_items.LockItemsForWrite(true); | ||
269 | m_items[item.ItemID].PermsMask = 0; | 280 | m_items[item.ItemID].PermsMask = 0; |
270 | m_items[item.ItemID].PermsGranter = UUID.Zero; | 281 | m_items[item.ItemID].PermsGranter = UUID.Zero; |
282 | m_items.LockItemsForWrite(false); | ||
271 | string script = Utils.BytesToString(asset.Data); | 283 | string script = Utils.BytesToString(asset.Data); |
272 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( | 284 | m_part.ParentGroup.Scene.EventManager.TriggerRezScript( |
273 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); | 285 | m_part.LocalId, item.ItemID, script, startParam, postOnRez, engine, stateSource); |
@@ -302,20 +314,22 @@ namespace OpenSim.Region.Framework.Scenes | |||
302 | /// </param> | 314 | /// </param> |
303 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) | 315 | public void CreateScriptInstance(UUID itemId, int startParam, bool postOnRez, string engine, int stateSource) |
304 | { | 316 | { |
305 | lock (m_items) | 317 | m_items.LockItemsForRead(true); |
318 | if (m_items.ContainsKey(itemId)) | ||
306 | { | 319 | { |
307 | if (m_items.ContainsKey(itemId)) | 320 | TaskInventoryItem item = m_items[itemId]; |
308 | { | 321 | m_items.LockItemsForRead(false); |
309 | CreateScriptInstance(m_items[itemId], startParam, postOnRez, engine, stateSource); | 322 | CreateScriptInstance(item, startParam, postOnRez, engine, stateSource); |
310 | } | ||
311 | else | ||
312 | { | ||
313 | m_log.ErrorFormat( | ||
314 | "[PRIM INVENTORY]: " + | ||
315 | "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}", | ||
316 | itemId, m_part.Name, m_part.UUID); | ||
317 | } | ||
318 | } | 323 | } |
324 | else | ||
325 | { | ||
326 | m_items.LockItemsForRead(false); | ||
327 | m_log.ErrorFormat( | ||
328 | "[PRIM INVENTORY]: " + | ||
329 | "Couldn't start script with ID {0} since it couldn't be found for prim {1}, {2}", | ||
330 | itemId, m_part.Name, m_part.UUID); | ||
331 | } | ||
332 | |||
319 | } | 333 | } |
320 | 334 | ||
321 | /// <summary> | 335 | /// <summary> |
@@ -346,11 +360,16 @@ namespace OpenSim.Region.Framework.Scenes | |||
346 | /// <returns></returns> | 360 | /// <returns></returns> |
347 | private bool InventoryContainsName(string name) | 361 | private bool InventoryContainsName(string name) |
348 | { | 362 | { |
349 | foreach (TaskInventoryItem item in Items.Values) | 363 | m_items.LockItemsForRead(true); |
364 | foreach (TaskInventoryItem item in m_items.Values) | ||
350 | { | 365 | { |
351 | if (item.Name == name) | 366 | if (item.Name == name) |
367 | { | ||
368 | m_items.LockItemsForRead(false); | ||
352 | return true; | 369 | return true; |
370 | } | ||
353 | } | 371 | } |
372 | m_items.LockItemsForRead(false); | ||
354 | return false; | 373 | return false; |
355 | } | 374 | } |
356 | 375 | ||
@@ -392,7 +411,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
392 | /// <param name="item"></param> | 411 | /// <param name="item"></param> |
393 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) | 412 | public void AddInventoryItemExclusive(TaskInventoryItem item, bool allowedDrop) |
394 | { | 413 | { |
414 | m_items.LockItemsForRead(true); | ||
395 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); | 415 | List<TaskInventoryItem> il = new List<TaskInventoryItem>(m_items.Values); |
416 | m_items.LockItemsForRead(false); | ||
396 | foreach (TaskInventoryItem i in il) | 417 | foreach (TaskInventoryItem i in il) |
397 | { | 418 | { |
398 | if (i.Name == item.Name) | 419 | if (i.Name == item.Name) |
@@ -429,15 +450,14 @@ namespace OpenSim.Region.Framework.Scenes | |||
429 | item.ParentPartID = m_part.UUID; | 450 | item.ParentPartID = m_part.UUID; |
430 | item.Name = name; | 451 | item.Name = name; |
431 | 452 | ||
432 | lock (m_items) | 453 | m_items.LockItemsForWrite(true); |
433 | { | 454 | m_items.Add(item.ItemID, item); |
434 | m_items.Add(item.ItemID, item); | 455 | m_items.LockItemsForWrite(false); |
435 | |||
436 | if (allowedDrop) | 456 | if (allowedDrop) |
437 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); | 457 | m_part.TriggerScriptChangedEvent(Changed.ALLOWED_DROP); |
438 | else | 458 | else |
439 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 459 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
440 | } | 460 | |
441 | 461 | ||
442 | m_inventorySerial++; | 462 | m_inventorySerial++; |
443 | //m_inventorySerial += 2; | 463 | //m_inventorySerial += 2; |
@@ -454,14 +474,13 @@ namespace OpenSim.Region.Framework.Scenes | |||
454 | /// <param name="items"></param> | 474 | /// <param name="items"></param> |
455 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) | 475 | public void RestoreInventoryItems(ICollection<TaskInventoryItem> items) |
456 | { | 476 | { |
457 | lock (m_items) | 477 | m_items.LockItemsForWrite(true); |
478 | foreach (TaskInventoryItem item in items) | ||
458 | { | 479 | { |
459 | foreach (TaskInventoryItem item in items) | 480 | m_items.Add(item.ItemID, item); |
460 | { | 481 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
461 | m_items.Add(item.ItemID, item); | ||
462 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
463 | } | ||
464 | } | 482 | } |
483 | m_items.LockItemsForWrite(false); | ||
465 | 484 | ||
466 | m_inventorySerial++; | 485 | m_inventorySerial++; |
467 | } | 486 | } |
@@ -474,8 +493,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
474 | public TaskInventoryItem GetInventoryItem(UUID itemId) | 493 | public TaskInventoryItem GetInventoryItem(UUID itemId) |
475 | { | 494 | { |
476 | TaskInventoryItem item; | 495 | TaskInventoryItem item; |
496 | m_items.LockItemsForRead(true); | ||
477 | m_items.TryGetValue(itemId, out item); | 497 | m_items.TryGetValue(itemId, out item); |
478 | 498 | m_items.LockItemsForRead(false); | |
479 | return item; | 499 | return item; |
480 | } | 500 | } |
481 | 501 | ||
@@ -487,45 +507,45 @@ namespace OpenSim.Region.Framework.Scenes | |||
487 | /// <returns>false if the item did not exist, true if the update occurred successfully</returns> | 507 | /// <returns>false if the item did not exist, true if the update occurred successfully</returns> |
488 | public bool UpdateInventoryItem(TaskInventoryItem item) | 508 | public bool UpdateInventoryItem(TaskInventoryItem item) |
489 | { | 509 | { |
490 | lock (m_items) | 510 | m_items.LockItemsForWrite(true); |
511 | |||
512 | if (m_items.ContainsKey(item.ItemID)) | ||
491 | { | 513 | { |
492 | if (m_items.ContainsKey(item.ItemID)) | 514 | item.ParentID = m_part.UUID; |
515 | item.ParentPartID = m_part.UUID; | ||
516 | item.Flags = m_items[item.ItemID].Flags; | ||
517 | if (item.AssetID == UUID.Zero) | ||
493 | { | 518 | { |
494 | item.ParentID = m_part.UUID; | 519 | item.AssetID = m_items[item.ItemID].AssetID; |
495 | item.ParentPartID = m_part.UUID; | 520 | } |
496 | item.Flags = m_items[item.ItemID].Flags; | 521 | else if ((InventoryType)item.Type == InventoryType.Notecard) |
497 | if (item.AssetID == UUID.Zero) | 522 | { |
498 | { | 523 | ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID); |
499 | item.AssetID = m_items[item.ItemID].AssetID; | ||
500 | } | ||
501 | else if ((InventoryType)item.Type == InventoryType.Notecard) | ||
502 | { | ||
503 | ScenePresence presence = m_part.ParentGroup.Scene.GetScenePresence(item.OwnerID); | ||
504 | 524 | ||
505 | if (presence != null) | 525 | if (presence != null) |
506 | { | 526 | { |
507 | presence.ControllingClient.SendAgentAlertMessage( | 527 | presence.ControllingClient.SendAgentAlertMessage( |
508 | "Notecard saved", false); | 528 | "Notecard saved", false); |
509 | } | ||
510 | } | 529 | } |
530 | } | ||
511 | 531 | ||
512 | m_items[item.ItemID] = item; | 532 | m_items[item.ItemID] = item; |
513 | m_inventorySerial++; | 533 | m_inventorySerial++; |
514 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | 534 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
515 | |||
516 | HasInventoryChanged = true; | ||
517 | m_part.ParentGroup.HasGroupChanged = true; | ||
518 | 535 | ||
519 | return true; | 536 | HasInventoryChanged = true; |
520 | } | 537 | m_part.ParentGroup.HasGroupChanged = true; |
521 | else | 538 | m_items.LockItemsForWrite(false); |
522 | { | 539 | return true; |
523 | m_log.ErrorFormat( | 540 | } |
524 | "[PRIM INVENTORY]: " + | 541 | else |
525 | "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", | 542 | { |
526 | item.ItemID, m_part.Name, m_part.UUID); | 543 | m_log.ErrorFormat( |
527 | } | 544 | "[PRIM INVENTORY]: " + |
545 | "Tried to retrieve item ID {0} from prim {1}, {2} but the item does not exist in this inventory", | ||
546 | item.ItemID, m_part.Name, m_part.UUID); | ||
528 | } | 547 | } |
548 | m_items.LockItemsForWrite(false); | ||
529 | 549 | ||
530 | return false; | 550 | return false; |
531 | } | 551 | } |
@@ -538,51 +558,54 @@ namespace OpenSim.Region.Framework.Scenes | |||
538 | /// in this prim's inventory.</returns> | 558 | /// in this prim's inventory.</returns> |
539 | public int RemoveInventoryItem(UUID itemID) | 559 | public int RemoveInventoryItem(UUID itemID) |
540 | { | 560 | { |
541 | lock (m_items) | 561 | m_items.LockItemsForRead(true); |
562 | |||
563 | if (m_items.ContainsKey(itemID)) | ||
542 | { | 564 | { |
543 | if (m_items.ContainsKey(itemID)) | 565 | int type = m_items[itemID].InvType; |
566 | m_items.LockItemsForRead(false); | ||
567 | if (type == 10) // Script | ||
544 | { | 568 | { |
545 | int type = m_items[itemID].InvType; | 569 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); |
546 | if (type == 10) // Script | 570 | } |
547 | { | 571 | m_items.LockItemsForWrite(true); |
548 | m_part.ParentGroup.Scene.EventManager.TriggerRemoveScript(m_part.LocalId, itemID); | 572 | m_items.Remove(itemID); |
549 | } | 573 | m_items.LockItemsForWrite(false); |
550 | m_items.Remove(itemID); | 574 | m_inventorySerial++; |
551 | m_inventorySerial++; | 575 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); |
552 | m_part.TriggerScriptChangedEvent(Changed.INVENTORY); | ||
553 | |||
554 | HasInventoryChanged = true; | ||
555 | m_part.ParentGroup.HasGroupChanged = true; | ||
556 | 576 | ||
557 | int scriptcount = 0; | 577 | HasInventoryChanged = true; |
558 | lock (m_items) | 578 | m_part.ParentGroup.HasGroupChanged = true; |
559 | { | ||
560 | foreach (TaskInventoryItem item in m_items.Values) | ||
561 | { | ||
562 | if (item.Type == 10) | ||
563 | { | ||
564 | scriptcount++; | ||
565 | } | ||
566 | } | ||
567 | } | ||
568 | 579 | ||
569 | if (scriptcount <= 0) | 580 | int scriptcount = 0; |
581 | m_items.LockItemsForRead(true); | ||
582 | foreach (TaskInventoryItem item in m_items.Values) | ||
583 | { | ||
584 | if (item.Type == 10) | ||
570 | { | 585 | { |
571 | m_part.RemFlag(PrimFlags.Scripted); | 586 | scriptcount++; |
572 | } | 587 | } |
573 | |||
574 | m_part.ScheduleFullUpdate(); | ||
575 | |||
576 | return type; | ||
577 | } | 588 | } |
578 | else | 589 | m_items.LockItemsForRead(false); |
590 | |||
591 | |||
592 | if (scriptcount <= 0) | ||
579 | { | 593 | { |
580 | m_log.ErrorFormat( | 594 | m_part.RemFlag(PrimFlags.Scripted); |
581 | "[PRIM INVENTORY]: " + | ||
582 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", | ||
583 | itemID, m_part.Name, m_part.UUID); | ||
584 | } | 595 | } |
596 | |||
597 | m_part.ScheduleFullUpdate(); | ||
598 | |||
599 | return type; | ||
600 | } | ||
601 | else | ||
602 | { | ||
603 | m_log.ErrorFormat( | ||
604 | "[PRIM INVENTORY]: " + | ||
605 | "Tried to remove item ID {0} from prim {1}, {2} but the item does not exist in this inventory", | ||
606 | itemID, m_part.Name, m_part.UUID); | ||
585 | } | 607 | } |
608 | m_items.LockItemsForWrite(false); | ||
586 | 609 | ||
587 | return -1; | 610 | return -1; |
588 | } | 611 | } |
@@ -635,52 +658,53 @@ namespace OpenSim.Region.Framework.Scenes | |||
635 | // isn't available (such as drag from prim inventory to agent inventory) | 658 | // isn't available (such as drag from prim inventory to agent inventory) |
636 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); | 659 | InventoryStringBuilder invString = new InventoryStringBuilder(m_part.UUID, UUID.Zero); |
637 | 660 | ||
638 | lock (m_items) | 661 | m_items.LockItemsForRead(true); |
662 | |||
663 | foreach (TaskInventoryItem item in m_items.Values) | ||
639 | { | 664 | { |
640 | foreach (TaskInventoryItem item in m_items.Values) | 665 | UUID ownerID = item.OwnerID; |
641 | { | 666 | uint everyoneMask = 0; |
642 | UUID ownerID = item.OwnerID; | 667 | uint baseMask = item.BasePermissions; |
643 | uint everyoneMask = 0; | 668 | uint ownerMask = item.CurrentPermissions; |
644 | uint baseMask = item.BasePermissions; | ||
645 | uint ownerMask = item.CurrentPermissions; | ||
646 | 669 | ||
647 | invString.AddItemStart(); | 670 | invString.AddItemStart(); |
648 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); | 671 | invString.AddNameValueLine("item_id", item.ItemID.ToString()); |
649 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); | 672 | invString.AddNameValueLine("parent_id", m_part.UUID.ToString()); |
650 | 673 | ||
651 | invString.AddPermissionsStart(); | 674 | invString.AddPermissionsStart(); |
652 | 675 | ||
653 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); | 676 | invString.AddNameValueLine("base_mask", Utils.UIntToHexString(baseMask)); |
654 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); | 677 | invString.AddNameValueLine("owner_mask", Utils.UIntToHexString(ownerMask)); |
655 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); | 678 | invString.AddNameValueLine("group_mask", Utils.UIntToHexString(0)); |
656 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); | 679 | invString.AddNameValueLine("everyone_mask", Utils.UIntToHexString(everyoneMask)); |
657 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); | 680 | invString.AddNameValueLine("next_owner_mask", Utils.UIntToHexString(item.NextPermissions)); |
658 | 681 | ||
659 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); | 682 | invString.AddNameValueLine("creator_id", item.CreatorID.ToString()); |
660 | invString.AddNameValueLine("owner_id", ownerID.ToString()); | 683 | invString.AddNameValueLine("owner_id", ownerID.ToString()); |
661 | 684 | ||
662 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); | 685 | invString.AddNameValueLine("last_owner_id", item.LastOwnerID.ToString()); |
663 | 686 | ||
664 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); | 687 | invString.AddNameValueLine("group_id", item.GroupID.ToString()); |
665 | invString.AddSectionEnd(); | 688 | invString.AddSectionEnd(); |
666 | 689 | ||
667 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); | 690 | invString.AddNameValueLine("asset_id", item.AssetID.ToString()); |
668 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); | 691 | invString.AddNameValueLine("type", TaskInventoryItem.Types[item.Type]); |
669 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); | 692 | invString.AddNameValueLine("inv_type", TaskInventoryItem.InvTypes[item.InvType]); |
670 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); | 693 | invString.AddNameValueLine("flags", Utils.UIntToHexString(item.Flags)); |
671 | 694 | ||
672 | invString.AddSaleStart(); | 695 | invString.AddSaleStart(); |
673 | invString.AddNameValueLine("sale_type", "not"); | 696 | invString.AddNameValueLine("sale_type", "not"); |
674 | invString.AddNameValueLine("sale_price", "0"); | 697 | invString.AddNameValueLine("sale_price", "0"); |
675 | invString.AddSectionEnd(); | 698 | invString.AddSectionEnd(); |
676 | 699 | ||
677 | invString.AddNameValueLine("name", item.Name + "|"); | 700 | invString.AddNameValueLine("name", item.Name + "|"); |
678 | invString.AddNameValueLine("desc", item.Description + "|"); | 701 | invString.AddNameValueLine("desc", item.Description + "|"); |
679 | 702 | ||
680 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); | 703 | invString.AddNameValueLine("creation_date", item.CreationDate.ToString()); |
681 | invString.AddSectionEnd(); | 704 | invString.AddSectionEnd(); |
682 | } | ||
683 | } | 705 | } |
706 | int count = m_items.Count; | ||
707 | m_items.LockItemsForRead(false); | ||
684 | 708 | ||
685 | fileData = Utils.StringToBytes(invString.BuildString); | 709 | fileData = Utils.StringToBytes(invString.BuildString); |
686 | 710 | ||
@@ -689,6 +713,7 @@ namespace OpenSim.Region.Framework.Scenes | |||
689 | 713 | ||
690 | if (fileData.Length > 2) | 714 | if (fileData.Length > 2) |
691 | { | 715 | { |
716 | m_log.Debug("Sending task inventory list of " + count.ToString() + " items to client " + client.AgentId.ToString()); | ||
692 | xferManager.AddNewFile(m_inventoryFileName, fileData); | 717 | xferManager.AddNewFile(m_inventoryFileName, fileData); |
693 | } | 718 | } |
694 | } | 719 | } |
@@ -701,10 +726,9 @@ namespace OpenSim.Region.Framework.Scenes | |||
701 | { | 726 | { |
702 | if (HasInventoryChanged) | 727 | if (HasInventoryChanged) |
703 | { | 728 | { |
704 | lock (Items) | 729 | Items.LockItemsForRead(true); |
705 | { | 730 | datastore.StorePrimInventory(m_part.UUID, Items.Values); |
706 | datastore.StorePrimInventory(m_part.UUID, Items.Values); | 731 | Items.LockItemsForRead(false); |
707 | } | ||
708 | 732 | ||
709 | HasInventoryChanged = false; | 733 | HasInventoryChanged = false; |
710 | } | 734 | } |
diff --git a/OpenSim/Region/Framework/Scenes/ScenePresence.cs b/OpenSim/Region/Framework/Scenes/ScenePresence.cs index 4e5fee1..4c8c94f 100644 --- a/OpenSim/Region/Framework/Scenes/ScenePresence.cs +++ b/OpenSim/Region/Framework/Scenes/ScenePresence.cs | |||
@@ -1615,21 +1615,19 @@ namespace OpenSim.Region.Framework.Scenes | |||
1615 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); | 1615 | SceneObjectPart part = m_scene.GetSceneObjectPart(m_parentID); |
1616 | if (part != null) | 1616 | if (part != null) |
1617 | { | 1617 | { |
1618 | part.TaskInventory.LockItemsForRead(true); | ||
1618 | TaskInventoryDictionary taskIDict = part.TaskInventory; | 1619 | TaskInventoryDictionary taskIDict = part.TaskInventory; |
1619 | if (taskIDict != null) | 1620 | if (taskIDict != null) |
1620 | { | 1621 | { |
1621 | lock (taskIDict) | 1622 | foreach (UUID taskID in taskIDict.Keys) |
1622 | { | 1623 | { |
1623 | foreach (UUID taskID in taskIDict.Keys) | 1624 | UnRegisterControlEventsToScript(LocalId, taskID); |
1624 | { | 1625 | taskIDict[taskID].PermsMask &= ~( |
1625 | UnRegisterControlEventsToScript(LocalId, taskID); | 1626 | 2048 | //PERMISSION_CONTROL_CAMERA |
1626 | taskIDict[taskID].PermsMask &= ~( | 1627 | 4); // PERMISSION_TAKE_CONTROLS |
1627 | 2048 | //PERMISSION_CONTROL_CAMERA | ||
1628 | 4); // PERMISSION_TAKE_CONTROLS | ||
1629 | } | ||
1630 | } | 1628 | } |
1631 | |||
1632 | } | 1629 | } |
1630 | part.TaskInventory.LockItemsForRead(false); | ||
1633 | // Reset sit target. | 1631 | // Reset sit target. |
1634 | if (part.GetAvatarOnSitTarget() == UUID) | 1632 | if (part.GetAvatarOnSitTarget() == UUID) |
1635 | part.SetAvatarOnSitTarget(UUID.Zero); | 1633 | part.SetAvatarOnSitTarget(UUID.Zero); |