aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
authorHomer Horwitz2008-11-08 17:00:42 +0000
committerHomer Horwitz2008-11-08 17:00:42 +0000
commit718425e7dc4e677cbed2a9757fe41417d1e6985e (patch)
tree5566be02bffebbbf0700b5b5c1b881bea64c0bab
parentSmall bugfix for RemoveNeighbourRegion (diff)
downloadopensim-SC_OLD-718425e7dc4e677cbed2a9757fe41417d1e6985e.zip
opensim-SC_OLD-718425e7dc4e677cbed2a9757fe41417d1e6985e.tar.gz
opensim-SC_OLD-718425e7dc4e677cbed2a9757fe41417d1e6985e.tar.bz2
opensim-SC_OLD-718425e7dc4e677cbed2a9757fe41417d1e6985e.tar.xz
Added necessary locking to LandManagementModule. As it is used by several
threads concurrently, you'll get bad Heisenbugs without correct locking. This might fix Mantis#2413
-rw-r--r--OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs382
1 files changed, 239 insertions, 143 deletions
diff --git a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs
index a23ec4d..2235be0 100644
--- a/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs
+++ b/OpenSim/Region/Environment/Modules/World/Land/LandManagementModule.cs
@@ -59,11 +59,11 @@ namespace OpenSim.Region.Environment.Modules.World.Land
59 private LandChannel landChannel; 59 private LandChannel landChannel;
60 private Scene m_scene; 60 private Scene m_scene;
61 61
62 private readonly int[,] landIDList = new int[64, 64]; 62 private readonly int[,] m_landIDList = new int[64, 64];
63 private readonly Dictionary<int, ILandObject> landList = new Dictionary<int, ILandObject>(); 63 private readonly Dictionary<int, ILandObject> m_landList = new Dictionary<int, ILandObject>();
64 64
65 private bool landPrimCountTainted; 65 private bool m_landPrimCountTainted;
66 private int lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 66 private int m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
67 67
68 private bool m_allowedForcefulBans = true; 68 private bool m_allowedForcefulBans = true;
69 69
@@ -75,7 +75,7 @@ namespace OpenSim.Region.Environment.Modules.World.Land
75 public void Initialise(Scene scene, IConfigSource source) 75 public void Initialise(Scene scene, IConfigSource source)
76 { 76 {
77 m_scene = scene; 77 m_scene = scene;
78 landIDList.Initialize(); 78 m_landIDList.Initialize();
79 landChannel = new LandChannel(scene, this); 79 landChannel = new LandChannel(scene, this);
80 80
81 parcelInfoCache = new Cache(); 81 parcelInfoCache = new Cache();
@@ -154,13 +154,18 @@ namespace OpenSim.Region.Environment.Modules.World.Land
154 AllowedForcefulBans = forceful; 154 AllowedForcefulBans = forceful;
155 } 155 }
156 156
157 public void UpdateLandObject(int local_id, LandData newData) 157 public void UpdateLandObject(int local_id, LandData data)
158 { 158 {
159 if (landList.ContainsKey(local_id)) 159 LandData newData = data.Copy();
160 newData.LocalID = local_id;
161
162 lock (m_landList)
160 { 163 {
161 newData.LocalID = local_id; 164 if (m_landList.ContainsKey(local_id))
162 landList[local_id].landData = newData.Copy(); 165 {
163 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, landList[local_id]); 166 m_landList[local_id].landData = newData;
167 m_scene.EventManager.TriggerLandObjectUpdated((uint)local_id, m_landList[local_id]);
168 }
164 } 169 }
165 } 170 }
166 171
@@ -176,9 +181,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land
176 public void ResetSimLandObjects() 181 public void ResetSimLandObjects()
177 { 182 {
178 //Remove all the land objects in the sim and add a blank, full sim land object set to public 183 //Remove all the land objects in the sim and add a blank, full sim land object set to public
179 landList.Clear(); 184 lock (m_landList)
180 lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1; 185 {
181 landIDList.Initialize(); 186 m_landList.Clear();
187 m_lastLandLocalID = LandChannel.START_LAND_LOCAL_ID - 1;
188 m_landIDList.Initialize();
189 }
182 190
183 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene); 191 ILandObject fullSimParcel = new LandObject(UUID.Zero, false, m_scene);
184 192
@@ -193,7 +201,10 @@ namespace OpenSim.Region.Environment.Modules.World.Land
193 201
194 public List<ILandObject> AllParcels() 202 public List<ILandObject> AllParcels()
195 { 203 {
196 return new List<ILandObject>(landList.Values); 204 lock (m_landList)
205 {
206 return new List<ILandObject>(m_landList.Values);
207 }
197 } 208 }
198 209
199 public List<ILandObject> ParcelsNearPoint(Vector3 position) 210 public List<ILandObject> ParcelsNearPoint(Vector3 position)
@@ -240,9 +251,14 @@ namespace OpenSim.Region.Environment.Modules.World.Land
240 { 251 {
241 if (m_scene.RegionInfo.RegionID == regionID) 252 if (m_scene.RegionInfo.RegionID == regionID)
242 { 253 {
243 if (landList[localLandID] != null) 254 ILandObject parcelAvatarIsEntering;
255 lock (m_landList)
256 {
257 parcelAvatarIsEntering = m_landList[localLandID];
258 }
259
260 if (parcelAvatarIsEntering != null)
244 { 261 {
245 ILandObject parcelAvatarIsEntering = landList[localLandID];
246 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT) 262 if (avatar.AbsolutePosition.Z < LandChannel.BAN_LINE_SAFETY_HIEGHT)
247 { 263 {
248 if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID)) 264 if (parcelAvatarIsEntering.isBannedFromLand(avatar.UUID))
@@ -279,12 +295,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land
279 { 295 {
280 if (checkBan.isBannedFromLand(avatar.AgentId)) 296 if (checkBan.isBannedFromLand(avatar.AgentId))
281 { 297 {
282 checkBan.sendLandProperties(-30000, false, (int)ParcelResult.Single, avatar); 298 checkBan.sendLandProperties((int)ParcelStatus.CollisionBanned, false, (int)ParcelResult.Single, avatar);
283 return; //Only send one 299 return; //Only send one
284 } 300 }
285 if (checkBan.isRestrictedFromLand(avatar.AgentId)) 301 if (checkBan.isRestrictedFromLand(avatar.AgentId))
286 { 302 {
287 checkBan.sendLandProperties(-40000, false, (int)ParcelResult.Single, avatar); 303 checkBan.sendLandProperties((int)ParcelStatus.CollisionNotOnAccessList, false, (int)ParcelResult.Single, avatar);
288 return; //Only send one 304 return; //Only send one
289 } 305 }
290 } 306 }
@@ -376,9 +392,15 @@ namespace OpenSim.Region.Environment.Modules.World.Land
376 public void handleParcelAccessRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID, 392 public void handleParcelAccessRequest(UUID agentID, UUID sessionID, uint flags, int sequenceID,
377 int landLocalID, IClientAPI remote_client) 393 int landLocalID, IClientAPI remote_client)
378 { 394 {
379 if (landList.ContainsKey(landLocalID)) 395 ILandObject land;
396 lock (m_landList)
380 { 397 {
381 landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client); 398 m_landList.TryGetValue(landLocalID, out land);
399 }
400
401 if (land != null)
402 {
403 m_landList[landLocalID].sendAccessList(agentID, sessionID, flags, sequenceID, remote_client);
382 } 404 }
383 } 405 }
384 406
@@ -386,16 +408,22 @@ namespace OpenSim.Region.Environment.Modules.World.Land
386 List<ParcelManager.ParcelAccessEntry> entries, 408 List<ParcelManager.ParcelAccessEntry> entries,
387 IClientAPI remote_client) 409 IClientAPI remote_client)
388 { 410 {
389 if (landList.ContainsKey(landLocalID)) 411 ILandObject land;
412 lock (m_landList)
413 {
414 m_landList.TryGetValue(landLocalID, out land);
415 }
416
417 if (land != null)
390 { 418 {
391 if (agentID == landList[landLocalID].landData.OwnerID) 419 if (agentID == land.landData.OwnerID)
392 { 420 {
393 landList[landLocalID].updateAccessList(flags, entries, remote_client); 421 land.updateAccessList(flags, entries, remote_client);
394 } 422 }
395 } 423 }
396 else 424 else
397 { 425 {
398 Console.WriteLine("INVALID LOCAL LAND ID"); 426 m_log.WarnFormat("[LAND]: Invalid local land ID {0}", landLocalID);
399 } 427 }
400 } 428 }
401 429
@@ -412,24 +440,31 @@ namespace OpenSim.Region.Environment.Modules.World.Land
412 /// Adds a land object to the stored list and adds them to the landIDList to what they own 440 /// Adds a land object to the stored list and adds them to the landIDList to what they own
413 /// </summary> 441 /// </summary>
414 /// <param name="new_land">The land object being added</param> 442 /// <param name="new_land">The land object being added</param>
415 public ILandObject AddLandObject(ILandObject new_land) 443 public ILandObject AddLandObject(ILandObject land)
416 { 444 {
417 lastLandLocalID++; 445 ILandObject new_land = land.Copy();
418 new_land.landData.LocalID = lastLandLocalID;
419 landList.Add(lastLandLocalID, new_land.Copy());
420 446
421 bool[,] landBitmap = new_land.getLandBitmap(); 447 lock (m_landList)
422 for (int x = 0; x < 64; x++)
423 { 448 {
424 for (int y = 0; y < 64; y++) 449 int newLandLocalID = ++m_lastLandLocalID;
450 new_land.landData.LocalID = newLandLocalID;
451
452 bool[,] landBitmap = new_land.getLandBitmap();
453 for (int x = 0; x < 64; x++)
425 { 454 {
426 if (landBitmap[x, y]) 455 for (int y = 0; y < 64; y++)
427 { 456 {
428 landIDList[x, y] = lastLandLocalID; 457 if (landBitmap[x, y])
458 {
459 m_landIDList[x, y] = newLandLocalID;
460 }
429 } 461 }
430 } 462 }
463
464 m_landList.Add(newLandLocalID, new_land);
431 } 465 }
432 landList[lastLandLocalID].forceUpdateLandInfo(); 466
467 new_land.forceUpdateLandInfo();
433 m_scene.EventManager.TriggerLandObjectAdded(new_land); 468 m_scene.EventManager.TriggerLandObjectAdded(new_land);
434 return new_land; 469 return new_land;
435 } 470 }
@@ -440,32 +475,40 @@ namespace OpenSim.Region.Environment.Modules.World.Land
440 /// <param name="local_id">Land.localID of the peice of land to remove.</param> 475 /// <param name="local_id">Land.localID of the peice of land to remove.</param>
441 public void removeLandObject(int local_id) 476 public void removeLandObject(int local_id)
442 { 477 {
443 for (int x = 0; x < 64; x++) 478 lock (m_landList)
444 { 479 {
445 for (int y = 0; y < 64; y++) 480 for (int x = 0; x < 64; x++)
446 { 481 {
447 if (landIDList[x, y] == local_id) 482 for (int y = 0; y < 64; y++)
448 { 483 {
449 return; 484 if (m_landIDList[x, y] == local_id)
450 //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y); 485 {
486 m_log.WarnFormat("[LAND]: Not removing land object {0}; still being used at {1}, {2}",
487 local_id, x, y);
488 return;
489 //throw new Exception("Could not remove land object. Still being used at " + x + ", " + y);
490 }
451 } 491 }
452 } 492 }
453 }
454 493
455 m_scene.EventManager.TriggerLandObjectRemoved(landList[local_id].landData.GlobalID); 494 m_scene.EventManager.TriggerLandObjectRemoved(m_landList[local_id].landData.GlobalID);
456 landList.Remove(local_id); 495 m_landList.Remove(local_id);
496 }
457 } 497 }
458 498
459 private void performFinalLandJoin(ILandObject master, ILandObject slave) 499 private void performFinalLandJoin(ILandObject master, ILandObject slave)
460 { 500 {
461 bool[,] landBitmapSlave = slave.getLandBitmap(); 501 bool[,] landBitmapSlave = slave.getLandBitmap();
462 for (int x = 0; x < 64; x++) 502 lock (m_landList)
463 { 503 {
464 for (int y = 0; y < 64; y++) 504 for (int x = 0; x < 64; x++)
465 { 505 {
466 if (landBitmapSlave[x, y]) 506 for (int y = 0; y < 64; y++)
467 { 507 {
468 landIDList[x, y] = master.landData.LocalID; 508 if (landBitmapSlave[x, y])
509 {
510 m_landIDList[x, y] = master.landData.LocalID;
511 }
469 } 512 }
470 } 513 }
471 } 514 }
@@ -476,11 +519,11 @@ namespace OpenSim.Region.Environment.Modules.World.Land
476 519
477 public ILandObject GetLandObject(int parcelLocalID) 520 public ILandObject GetLandObject(int parcelLocalID)
478 { 521 {
479 lock (landList) 522 lock (m_landList)
480 { 523 {
481 if (landList.ContainsKey(parcelLocalID)) 524 if (m_landList.ContainsKey(parcelLocalID))
482 { 525 {
483 return landList[parcelLocalID]; 526 return m_landList[parcelLocalID];
484 } 527 }
485 } 528 }
486 return null; 529 return null;
@@ -511,7 +554,10 @@ namespace OpenSim.Region.Environment.Modules.World.Land
511 { 554 {
512 return null; 555 return null;
513 } 556 }
514 return landList[landIDList[x, y]]; 557 lock (m_landList)
558 {
559 return m_landList[m_landIDList[x, y]];
560 }
515 } 561 }
516 562
517 public ILandObject GetLandObject(int x, int y) 563 public ILandObject GetLandObject(int x, int y)
@@ -522,7 +568,10 @@ namespace OpenSim.Region.Environment.Modules.World.Land
522 // they happen every time at border crossings 568 // they happen every time at border crossings
523 throw new Exception("Error: Parcel not found at point " + x + ", " + y); 569 throw new Exception("Error: Parcel not found at point " + x + ", " + y);
524 } 570 }
525 return landList[landIDList[x / 4, y / 4]]; 571 lock (m_landIDList)
572 {
573 return m_landList[m_landIDList[x / 4, y / 4]];
574 }
526 } 575 }
527 576
528 #endregion 577 #endregion
@@ -531,20 +580,23 @@ namespace OpenSim.Region.Environment.Modules.World.Land
531 580
532 public void ResetAllLandPrimCounts() 581 public void ResetAllLandPrimCounts()
533 { 582 {
534 foreach (LandObject p in landList.Values) 583 lock (m_landList)
535 { 584 {
536 p.resetLandPrimCounts(); 585 foreach (LandObject p in m_landList.Values)
586 {
587 p.resetLandPrimCounts();
588 }
537 } 589 }
538 } 590 }
539 591
540 public void SetPrimsTainted() 592 public void SetPrimsTainted()
541 { 593 {
542 landPrimCountTainted = true; 594 m_landPrimCountTainted = true;
543 } 595 }
544 596
545 public bool IsLandPrimCountTainted() 597 public bool IsLandPrimCountTainted()
546 { 598 {
547 return landPrimCountTainted; 599 return m_landPrimCountTainted;
548 } 600 }
549 601
550 public void AddPrimToLandPrimCounts(SceneObjectGroup obj) 602 public void AddPrimToLandPrimCounts(SceneObjectGroup obj)
@@ -559,32 +611,46 @@ namespace OpenSim.Region.Environment.Modules.World.Land
559 611
560 public void RemovePrimFromLandPrimCounts(SceneObjectGroup obj) 612 public void RemovePrimFromLandPrimCounts(SceneObjectGroup obj)
561 { 613 {
562 foreach (LandObject p in landList.Values) 614
615 lock (m_landList)
563 { 616 {
564 p.removePrimFromCount(obj); 617 foreach (LandObject p in m_landList.Values)
618 {
619 p.removePrimFromCount(obj);
620 }
565 } 621 }
566 } 622 }
567 623
568 public void FinalizeLandPrimCountUpdate() 624 public void FinalizeLandPrimCountUpdate()
569 { 625 {
626 m_log.Debug("Called FinalizeLandPrimCountUpdate start");
570 //Get Simwide prim count for owner 627 //Get Simwide prim count for owner
571 Dictionary<UUID, List<LandObject>> landOwnersAndParcels = new Dictionary<UUID, List<LandObject>>(); 628 Dictionary<UUID, List<LandObject>> landOwnersAndParcels = new Dictionary<UUID, List<LandObject>>();
572 foreach (LandObject p in landList.Values) 629 lock (m_landList)
573 { 630 {
574 if (!landOwnersAndParcels.ContainsKey(p.landData.OwnerID)) 631 m_log.DebugFormat("[LAND]: Got {0} parcels", m_landList.Count);
632 foreach (LandObject p in m_landList.Values)
575 { 633 {
576 List<LandObject> tempList = new List<LandObject>(); 634 m_log.DebugFormat("processing land {0}", p.GetHashCode());
577 tempList.Add(p); 635 if (!landOwnersAndParcels.ContainsKey(p.landData.OwnerID))
578 landOwnersAndParcels.Add(p.landData.OwnerID, tempList); 636 {
579 } 637 m_log.DebugFormat("adding new owner {0} to landlist", p.landData.OwnerID);
580 else 638 List<LandObject> tempList = new List<LandObject>();
581 { 639 tempList.Add(p);
582 landOwnersAndParcels[p.landData.OwnerID].Add(p); 640 landOwnersAndParcels.Add(p.landData.OwnerID, tempList);
641 }
642 else
643 {
644 m_log.DebugFormat("adding to owner {0}", p.landData.OwnerID);
645 landOwnersAndParcels[p.landData.OwnerID].Add(p);
646 }
583 } 647 }
584 } 648 }
585 649
650 m_log.DebugFormat("got {0} owners of land", landOwnersAndParcels.Count);
586 foreach (UUID owner in landOwnersAndParcels.Keys) 651 foreach (UUID owner in landOwnersAndParcels.Keys)
587 { 652 {
653 m_log.DebugFormat("processing owner {0}", owner);
588 int simArea = 0; 654 int simArea = 0;
589 int simPrims = 0; 655 int simPrims = 0;
590 foreach (LandObject p in landOwnersAndParcels[owner]) 656 foreach (LandObject p in landOwnersAndParcels[owner])
@@ -592,18 +658,23 @@ namespace OpenSim.Region.Environment.Modules.World.Land
592 simArea += p.landData.Area; 658 simArea += p.landData.Area;
593 simPrims += p.landData.OwnerPrims + p.landData.OtherPrims + p.landData.GroupPrims + 659 simPrims += p.landData.OwnerPrims + p.landData.OtherPrims + p.landData.GroupPrims +
594 p.landData.SelectedPrims; 660 p.landData.SelectedPrims;
661 m_log.DebugFormat("added {0} m² of land, total {1}", p.landData.Area, simArea);
595 } 662 }
596 663
664 m_log.DebugFormat("setting total area of {0} to {1} for {2} parcels", owner, simArea, landOwnersAndParcels[owner].Count);
597 foreach (LandObject p in landOwnersAndParcels[owner]) 665 foreach (LandObject p in landOwnersAndParcels[owner])
598 { 666 {
667 m_log.DebugFormat("... in land {0}", p.GetHashCode());
599 p.landData.SimwideArea = simArea; 668 p.landData.SimwideArea = simArea;
600 p.landData.SimwidePrims = simPrims; 669 p.landData.SimwidePrims = simPrims;
601 } 670 }
602 } 671 }
672 m_log.Debug("Called FinalizeLandPrimCountUpdate end");
603 } 673 }
604 674
605 public void UpdateLandPrimCounts() 675 public void UpdateLandPrimCounts()
606 { 676 {
677 m_log.Debug("Called UpdateLandPrimCounts");
607 ResetAllLandPrimCounts(); 678 ResetAllLandPrimCounts();
608 lock (m_scene.Entities) 679 lock (m_scene.Entities)
609 { 680 {
@@ -619,15 +690,16 @@ namespace OpenSim.Region.Environment.Modules.World.Land
619 } 690 }
620 } 691 }
621 FinalizeLandPrimCountUpdate(); 692 FinalizeLandPrimCountUpdate();
622 landPrimCountTainted = false; 693 m_landPrimCountTainted = false;
623 } 694 }
624 695
625 public void PerformParcelPrimCountUpdate() 696 public void PerformParcelPrimCountUpdate()
626 { 697 {
698 m_log.Debug("Called PerformParcelPrimCountUpdate");
627 ResetAllLandPrimCounts(); 699 ResetAllLandPrimCounts();
628 m_scene.EventManager.TriggerParcelPrimCountUpdate(); 700 m_scene.EventManager.TriggerParcelPrimCountUpdate();
629 FinalizeLandPrimCountUpdate(); 701 FinalizeLandPrimCountUpdate();
630 landPrimCountTainted = false; 702 m_landPrimCountTainted = false;
631 } 703 }
632 704
633 /// <summary> 705 /// <summary>
@@ -684,9 +756,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land
684 756
685 //Now, lets set the subdivision area of the original to false 757 //Now, lets set the subdivision area of the original to false
686 int startLandObjectIndex = startLandObject.landData.LocalID; 758 int startLandObjectIndex = startLandObject.landData.LocalID;
687 landList[startLandObjectIndex].setLandBitmap( 759 lock (m_landList)
688 newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false)); 760 {
689 landList[startLandObjectIndex].forceUpdateLandInfo(); 761 m_landList[startLandObjectIndex].setLandBitmap(
762 newLand.modifyLandBitmapSquare(startLandObject.getLandBitmap(), start_x, start_y, end_x, end_y, false));
763 m_landList[startLandObjectIndex].forceUpdateLandInfo();
764 }
690 765
691 SetPrimsTainted(); 766 SetPrimsTainted();
692 767
@@ -746,13 +821,16 @@ namespace OpenSim.Region.Environment.Modules.World.Land
746 return; 821 return;
747 } 822 }
748 } 823 }
749 foreach (ILandObject slaveLandObject in selectedLandObjects) 824
825 lock (m_landList)
750 { 826 {
751 landList[masterLandObject.landData.LocalID].setLandBitmap( 827 foreach (ILandObject slaveLandObject in selectedLandObjects)
752 slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap())); 828 {
753 performFinalLandJoin(masterLandObject, slaveLandObject); 829 m_landList[masterLandObject.landData.LocalID].setLandBitmap(
830 slaveLandObject.mergeLandBitmaps(masterLandObject.getLandBitmap(), slaveLandObject.getLandBitmap()));
831 performFinalLandJoin(masterLandObject, slaveLandObject);
832 }
754 } 833 }
755
756 SetPrimsTainted(); 834 SetPrimsTainted();
757 835
758 masterLandObject.sendLandUpdateToAvatarsOverMe(); 836 masterLandObject.sendLandUpdateToAvatarsOverMe();
@@ -892,10 +970,13 @@ namespace OpenSim.Region.Environment.Modules.World.Land
892 970
893 public void handleParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client) 971 public void handleParcelPropertiesUpdateRequest(LandUpdateArgs args, int localID, IClientAPI remote_client)
894 { 972 {
895 if (landList.ContainsKey(localID)) 973 ILandObject land;
974 lock (m_landList)
896 { 975 {
897 landList[localID].updateLandProperties(args, remote_client); 976 m_landList.TryGetValue(localID, out land);
898 } 977 }
978
979 if (land != null) land.updateLandProperties(args, remote_client);
899 } 980 }
900 981
901 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client) 982 public void handleParcelDivideRequest(int west, int south, int east, int north, IClientAPI remote_client)
@@ -910,67 +991,88 @@ namespace OpenSim.Region.Environment.Modules.World.Land
910 991
911 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client) 992 public void handleParcelSelectObjectsRequest(int local_id, int request_type, IClientAPI remote_client)
912 { 993 {
913 landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client); 994 m_landList[local_id].sendForceObjectSelect(local_id, request_type, remote_client);
914 } 995 }
915 996
916 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client) 997 public void handleParcelObjectOwnersRequest(int local_id, IClientAPI remote_client)
917 { 998 {
918 lock (landList) 999 ILandObject land;
1000 lock (m_landList)
919 { 1001 {
920 if (landList.ContainsKey(local_id)) 1002 m_landList.TryGetValue(local_id, out land);
921 { 1003 }
922 landList[local_id].sendLandObjectOwners(remote_client); 1004
923 } 1005 if (land != null)
924 else 1006 {
925 { 1007 m_landList[local_id].sendLandObjectOwners(remote_client);
926 System.Console.WriteLine("[PARCEL]: Invalid land object passed for parcel object owner request"); 1008 }
927 } 1009 else
1010 {
1011 m_log.WarnFormat("[PARCEL]: Invalid land object {0} passed for parcel object owner request", local_id);
928 } 1012 }
929 } 1013 }
930 1014
931 public void handleParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client) 1015 public void handleParcelGodForceOwner(int local_id, UUID ownerID, IClientAPI remote_client)
932 { 1016 {
933 if (landList.ContainsKey(local_id)) 1017 ILandObject land;
1018 lock (m_landList)
1019 {
1020 m_landList.TryGetValue(local_id, out land);
1021 }
1022
1023 if (land != null)
934 { 1024 {
935 if (m_scene.ExternalChecks.ExternalChecksCanBeGodLike(remote_client.AgentId)) 1025 if (m_scene.ExternalChecks.ExternalChecksCanBeGodLike(remote_client.AgentId))
936 { 1026 {
937 landList[local_id].landData.OwnerID = ownerID; 1027 land.landData.OwnerID = ownerID;
938 1028
939 m_scene.Broadcast(SendParcelOverlay); 1029 m_scene.Broadcast(SendParcelOverlay);
940 landList[local_id].sendLandUpdateToClient(remote_client); 1030 land.sendLandUpdateToClient(remote_client);
941 } 1031 }
942 } 1032 }
943 } 1033 }
944 1034
945 public void handleParcelAbandonRequest(int local_id, IClientAPI remote_client) 1035 public void handleParcelAbandonRequest(int local_id, IClientAPI remote_client)
946 { 1036 {
947 if (landList.ContainsKey(local_id)) 1037 ILandObject land;
1038 lock (m_landList)
948 { 1039 {
949 if (m_scene.ExternalChecks.ExternalChecksCanAbandonParcel(remote_client.AgentId, landList[local_id])) 1040 m_landList.TryGetValue(local_id, out land);
1041 }
1042
1043 if (land != null)
1044 {
1045 if (m_scene.ExternalChecks.ExternalChecksCanAbandonParcel(remote_client.AgentId, land))
950 { 1046 {
951 if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) 1047 if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero)
952 landList[local_id].landData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 1048 land.landData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
953 else 1049 else
954 landList[local_id].landData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; 1050 land.landData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
955 m_scene.Broadcast(SendParcelOverlay); 1051 m_scene.Broadcast(SendParcelOverlay);
956 landList[local_id].sendLandUpdateToClient(remote_client); 1052 land.sendLandUpdateToClient(remote_client);
957 } 1053 }
958 } 1054 }
959 } 1055 }
960 1056
961 public void handleParcelReclaim(int local_id, IClientAPI remote_client) 1057 public void handleParcelReclaim(int local_id, IClientAPI remote_client)
962 { 1058 {
963 if (landList.ContainsKey(local_id)) 1059 ILandObject land;
1060 lock (m_landList)
1061 {
1062 m_landList.TryGetValue(local_id, out land);
1063 }
1064
1065 if (land != null)
964 { 1066 {
965 if (m_scene.ExternalChecks.ExternalChecksCanReclaimParcel(remote_client.AgentId, landList[local_id])) 1067 if (m_scene.ExternalChecks.ExternalChecksCanReclaimParcel(remote_client.AgentId, land))
966 { 1068 {
967 if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero) 1069 if (m_scene.RegionInfo.EstateSettings.EstateOwner != UUID.Zero)
968 landList[local_id].landData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner; 1070 land.landData.OwnerID = m_scene.RegionInfo.EstateSettings.EstateOwner;
969 else 1071 else
970 landList[local_id].landData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID; 1072 land.landData.OwnerID = m_scene.RegionInfo.MasterAvatarAssignedUUID;
971 landList[local_id].landData.ClaimDate = Util.UnixTimeSinceEpoch(); 1073 land.landData.ClaimDate = Util.UnixTimeSinceEpoch();
972 m_scene.Broadcast(SendParcelOverlay); 1074 m_scene.Broadcast(SendParcelOverlay);
973 landList[local_id].sendLandUpdateToClient(remote_client); 1075 land.sendLandUpdateToClient(remote_client);
974 } 1076 }
975 } 1077 }
976 } 1078 }
@@ -984,13 +1086,15 @@ namespace OpenSim.Region.Environment.Modules.World.Land
984 { 1086 {
985 if (e.economyValidated && e.landValidated) 1087 if (e.economyValidated && e.landValidated)
986 { 1088 {
987 lock (landList) 1089 ILandObject land;
1090 lock (m_landList)
988 { 1091 {
989 if (landList.ContainsKey(e.parcelLocalID)) 1092 m_landList.TryGetValue(e.parcelLocalID, out land);
990 { 1093 }
991 landList[e.parcelLocalID].updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint)e.transactionID, e.parcelPrice, e.parcelArea); 1094
992 return; 1095 if (land != null)
993 } 1096 {
1097 land.updateLandSold(e.agentId, e.groupId, e.groupOwned, (uint)e.transactionID, e.parcelPrice, e.parcelArea);
994 } 1098 }
995 } 1099 }
996 } 1100 }
@@ -1004,13 +1108,11 @@ namespace OpenSim.Region.Environment.Modules.World.Land
1004 if (e.landValidated == false) 1108 if (e.landValidated == false)
1005 { 1109 {
1006 ILandObject lob = null; 1110 ILandObject lob = null;
1007 lock (landList) 1111 lock (m_landList)
1008 { 1112 {
1009 if (landList.ContainsKey(e.parcelLocalID)) 1113 m_landList.TryGetValue(e.parcelLocalID, out lob);
1010 {
1011 lob = landList[e.parcelLocalID];
1012 }
1013 } 1114 }
1115
1014 if (lob != null) 1116 if (lob != null)
1015 { 1117 {
1016 UUID AuthorizedID = lob.landData.AuthBuyerID; 1118 UUID AuthorizedID = lob.landData.AuthBuyerID;
@@ -1021,11 +1123,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land
1021 (uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0); 1123 (uint)(Parcel.ParcelFlags.ForSale | Parcel.ParcelFlags.ForSaleObjects | Parcel.ParcelFlags.SellParcelObjects)) != 0);
1022 if ((AuthorizedID == UUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale) 1124 if ((AuthorizedID == UUID.Zero || AuthorizedID == e.agentId) && e.parcelPrice >= saleprice && landforsale)
1023 { 1125 {
1024 lock (e) 1126 // TODO I don't think we have to lock it here, no?
1025 { 1127 //lock (e)
1128 //{
1026 e.parcelOwnerID = pOwnerID; 1129 e.parcelOwnerID = pOwnerID;
1027 e.landValidated = true; 1130 e.landValidated = true;
1028 } 1131 //}
1029 } 1132 }
1030 } 1133 }
1031 } 1134 }
@@ -1037,20 +1140,8 @@ namespace OpenSim.Region.Environment.Modules.World.Land
1037 { 1140 {
1038 for (int i = 0; i < data.Count; i++) 1141 for (int i = 0; i < data.Count; i++)
1039 { 1142 {
1040 //try
1041 //{
1042 IncomingLandObjectFromStorage(data[i]); 1143 IncomingLandObjectFromStorage(data[i]);
1043 //} 1144 }
1044 //catch (Exception ex)
1045 //{
1046 //m_log.Error("[LandManager]: IncomingLandObjectsFromStorage: Exception: " + ex.ToString());
1047 //throw ex;
1048 //}
1049 }
1050 //foreach (LandData parcel in data)
1051 //{
1052 // IncomingLandObjectFromStorage(parcel);
1053 //}
1054 } 1145 }
1055 1146
1056 public void IncomingLandObjectFromStorage(LandData data) 1147 public void IncomingLandObjectFromStorage(LandData data)
@@ -1064,13 +1155,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land
1064 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient) 1155 public void ReturnObjectsInParcel(int localID, uint returnType, UUID[] agentIDs, UUID[] taskIDs, IClientAPI remoteClient)
1065 { 1156 {
1066 ILandObject selectedParcel = null; 1157 ILandObject selectedParcel = null;
1067 lock (landList) 1158 lock (m_landList)
1068 { 1159 {
1069 if (landList.ContainsKey(localID)) 1160 m_landList.TryGetValue(localID, out selectedParcel);
1070 selectedParcel = landList[localID];
1071 } 1161 }
1072 if (selectedParcel == null) 1162
1073 return; 1163 if (selectedParcel == null) return;
1074 1164
1075 if (returnType == 16) // parcel return 1165 if (returnType == 16) // parcel return
1076 { 1166 {
@@ -1087,9 +1177,12 @@ namespace OpenSim.Region.Environment.Modules.World.Land
1087 1177
1088 public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel) 1178 public void setParcelObjectMaxOverride(overrideParcelMaxPrimCountDelegate overrideDel)
1089 { 1179 {
1090 foreach (LandObject obj in landList.Values) 1180 lock (m_landList)
1091 { 1181 {
1092 obj.setParcelObjectMaxOverride(overrideDel); 1182 foreach (LandObject obj in m_landList.Values)
1183 {
1184 obj.setParcelObjectMaxOverride(overrideDel);
1185 }
1093 } 1186 }
1094 } 1187 }
1095 1188
@@ -1234,19 +1327,22 @@ namespace OpenSim.Region.Environment.Modules.World.Land
1234 m_log.Debug("[LAND] got no parcelinfo; not sending"); 1327 m_log.Debug("[LAND] got no parcelinfo; not sending");
1235 } 1328 }
1236 1329
1237 public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID,int otherCleanTime) 1330 public void setParcelOtherCleanTime(IClientAPI remoteClient, int localID, int otherCleanTime)
1238 { 1331 {
1239 if (!landList.ContainsKey(localID)) 1332 ILandObject land;
1240 return; 1333 lock (m_landList)
1334 {
1335 m_landList.TryGetValue(localID, out land);
1336 }
1241 1337
1242 ILandObject landObject = landList[localID]; 1338 if(land == null) return;
1243 1339
1244 if (!m_scene.ExternalChecks.ExternalChecksCanEditParcel(remoteClient.AgentId, landObject)) 1340 if (!m_scene.ExternalChecks.ExternalChecksCanEditParcel(remoteClient.AgentId, land))
1245 return; 1341 return;
1246 1342
1247 landObject.landData.OtherCleanTime = otherCleanTime; 1343 land.landData.OtherCleanTime = otherCleanTime;
1248 1344
1249 UpdateLandObject(localID, landObject.landData); 1345 UpdateLandObject(localID, land.landData);
1250 } 1346 }
1251 } 1347 }
1252} 1348}