aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/OpenSim/Region/Framework/Scenes/SceneGraph.cs
diff options
context:
space:
mode:
authorJohn Hurliman2010-09-10 12:04:12 -0700
committerJohn Hurliman2010-09-10 12:04:12 -0700
commitdd277a0d02f1aa79f4fcb5d108cbc696e90500c2 (patch)
tree7e396d347e43504ec23c59c3749f995f15c2e254 /OpenSim/Region/Framework/Scenes/SceneGraph.cs
parent* Run SimianGrid session updates asynchronously instead of from the main hear... (diff)
downloadopensim-SC_OLD-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.zip
opensim-SC_OLD-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.gz
opensim-SC_OLD-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.bz2
opensim-SC_OLD-dd277a0d02f1aa79f4fcb5d108cbc696e90500c2.tar.xz
First pass at cleaning up thread safety in EntityManager and SceneGraph
Diffstat (limited to 'OpenSim/Region/Framework/Scenes/SceneGraph.cs')
-rw-r--r--OpenSim/Region/Framework/Scenes/SceneGraph.cs263
1 files changed, 127 insertions, 136 deletions
diff --git a/OpenSim/Region/Framework/Scenes/SceneGraph.cs b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
index dfb26b9..3d3e822 100644
--- a/OpenSim/Region/Framework/Scenes/SceneGraph.cs
+++ b/OpenSim/Region/Framework/Scenes/SceneGraph.cs
@@ -348,68 +348,57 @@ namespace OpenSim.Region.Framework.Scenes
348 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero) 348 if (sceneObject == null || sceneObject.RootPart == null || sceneObject.RootPart.UUID == UUID.Zero)
349 return false; 349 return false;
350 350
351 lock (sceneObject) 351 if (Entities.ContainsKey(sceneObject.UUID))
352 { 352 return false;
353 if (Entities.ContainsKey(sceneObject.UUID)) 353
354 { 354 // Clamp child prim sizes and add child prims to the m_numPrim count
355// m_log.WarnFormat( 355 lock (sceneObject.Children)
356// "[SCENE GRAPH]: Scene object {0} {1} was already in region {2} on add request", 356 {
357// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName); 357 if (m_parentScene.m_clampPrimSize)
358 return false;
359 }
360
361// m_log.DebugFormat(
362// "[SCENE GRAPH]: Adding object {0} {1} to region {2}",
363// sceneObject.Name, sceneObject.UUID, m_parentScene.RegionInfo.RegionName);
364
365 lock (sceneObject.Children)
366 { 358 {
367 if (m_parentScene.m_clampPrimSize) 359 foreach (SceneObjectPart part in sceneObject.Children.Values)
368 { 360 {
369 foreach (SceneObjectPart part in sceneObject.Children.Values) 361 Vector3 scale = part.Shape.Scale;
370 { 362
371 Vector3 scale = part.Shape.Scale; 363 if (scale.X > m_parentScene.m_maxNonphys)
372 364 scale.X = m_parentScene.m_maxNonphys;
373 if (scale.X > m_parentScene.m_maxNonphys) 365 if (scale.Y > m_parentScene.m_maxNonphys)
374 scale.X = m_parentScene.m_maxNonphys; 366 scale.Y = m_parentScene.m_maxNonphys;
375 if (scale.Y > m_parentScene.m_maxNonphys) 367 if (scale.Z > m_parentScene.m_maxNonphys)
376 scale.Y = m_parentScene.m_maxNonphys; 368 scale.Z = m_parentScene.m_maxNonphys;
377 if (scale.Z > m_parentScene.m_maxNonphys) 369
378 scale.Z = m_parentScene.m_maxNonphys; 370 part.Shape.Scale = scale;
379
380 part.Shape.Scale = scale;
381 }
382 } 371 }
383
384 m_numPrim += sceneObject.Children.Count;
385 } 372 }
386
387 sceneObject.AttachToScene(m_parentScene);
388 373
389 if (sendClientUpdates) 374 m_numPrim += sceneObject.Children.Count;
390 sceneObject.ScheduleGroupForFullUpdate(); 375 }
391
392 Entities.Add(sceneObject);
393 376
394 if (attachToBackup) 377 sceneObject.AttachToScene(m_parentScene);
395 sceneObject.AttachToBackup();
396 378
397 if (OnObjectCreate != null) 379 if (sendClientUpdates)
398 OnObjectCreate(sceneObject); 380 sceneObject.ScheduleGroupForFullUpdate();
399 381
400 lock (SceneObjectGroupsByFullID) 382 Entities.Add(sceneObject);
401 { 383
402 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject; 384 if (attachToBackup)
403 foreach (SceneObjectPart part in sceneObject.Children.Values) 385 sceneObject.AttachToBackup();
404 SceneObjectGroupsByFullID[part.UUID] = sceneObject; 386
405 } 387 if (OnObjectCreate != null)
406 388 OnObjectCreate(sceneObject);
407 lock (SceneObjectGroupsByLocalID) 389
408 { 390 lock (SceneObjectGroupsByFullID)
409 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject; 391 {
410 foreach (SceneObjectPart part in sceneObject.Children.Values) 392 SceneObjectGroupsByFullID[sceneObject.UUID] = sceneObject;
411 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject; 393 foreach (SceneObjectPart part in sceneObject.Children.Values)
412 } 394 SceneObjectGroupsByFullID[part.UUID] = sceneObject;
395 }
396
397 lock (SceneObjectGroupsByLocalID)
398 {
399 SceneObjectGroupsByLocalID[sceneObject.LocalId] = sceneObject;
400 foreach (SceneObjectPart part in sceneObject.Children.Values)
401 SceneObjectGroupsByLocalID[part.LocalId] = sceneObject;
413 } 402 }
414 403
415 return true; 404 return true;
@@ -421,42 +410,38 @@ namespace OpenSim.Region.Framework.Scenes
421 /// <returns>true if the object was deleted, false if there was no object to delete</returns> 410 /// <returns>true if the object was deleted, false if there was no object to delete</returns>
422 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked) 411 public bool DeleteSceneObject(UUID uuid, bool resultOfObjectLinked)
423 { 412 {
424 if (Entities.ContainsKey(uuid)) 413 EntityBase entity;
425 { 414 if (!Entities.TryGetValue(uuid, out entity) && entity is SceneObjectGroup)
426 SceneObjectGroup grp = (SceneObjectGroup)Entities[uuid]; 415 return false;
427 416
428 if (!resultOfObjectLinked) 417 SceneObjectGroup grp = (SceneObjectGroup)entity;
429 {
430 m_numPrim -= grp.PrimCount;
431 418
432 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 419 if (!resultOfObjectLinked)
433 RemovePhysicalPrim(grp.PrimCount); 420 {
434 } 421 m_numPrim -= grp.PrimCount;
435 422
436 if (OnObjectRemove != null) 423 if ((grp.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics)
437 OnObjectRemove(Entities[uuid]); 424 RemovePhysicalPrim(grp.PrimCount);
425 }
438 426
439 lock (SceneObjectGroupsByFullID) 427 if (OnObjectRemove != null)
440 { 428 OnObjectRemove(Entities[uuid]);
441 foreach (SceneObjectPart part in grp.Children.Values)
442 SceneObjectGroupsByFullID.Remove(part.UUID);
443 SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
444 }
445 lock (SceneObjectGroupsByLocalID)
446 {
447 foreach (SceneObjectPart part in grp.Children.Values)
448 SceneObjectGroupsByLocalID.Remove(part.LocalId);
449 SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
450 }
451 429
452 Entities.Remove(uuid); 430 lock (SceneObjectGroupsByFullID)
453 //SceneObjectGroup part; 431 {
454 //((part.RootPart.Flags & PrimFlags.Physics) == PrimFlags.Physics) 432 foreach (SceneObjectPart part in grp.Children.Values)
433 SceneObjectGroupsByFullID.Remove(part.UUID);
434 SceneObjectGroupsByFullID.Remove(grp.RootPart.UUID);
435 }
455 436
456 return true; 437 lock (SceneObjectGroupsByLocalID)
438 {
439 foreach (SceneObjectPart part in grp.Children.Values)
440 SceneObjectGroupsByLocalID.Remove(part.LocalId);
441 SceneObjectGroupsByLocalID.Remove(grp.RootPart.LocalId);
457 } 442 }
458 443
459 return false; 444 return Entities.Remove(uuid);
460 } 445 }
461 446
462 /// <summary> 447 /// <summary>
@@ -468,9 +453,7 @@ namespace OpenSim.Region.Framework.Scenes
468 protected internal void AddToUpdateList(SceneObjectGroup obj) 453 protected internal void AddToUpdateList(SceneObjectGroup obj)
469 { 454 {
470 lock (m_updateList) 455 lock (m_updateList)
471 {
472 m_updateList[obj.UUID] = obj; 456 m_updateList[obj.UUID] = obj;
473 }
474 } 457 }
475 458
476 /// <summary> 459 /// <summary>
@@ -480,34 +463,39 @@ namespace OpenSim.Region.Framework.Scenes
480 { 463 {
481 if (!Monitor.TryEnter(m_updateLock)) 464 if (!Monitor.TryEnter(m_updateLock))
482 return; 465 return;
483 466 try
484 List<SceneObjectGroup> updates;
485
486 // Some updates add more updates to the updateList.
487 // Get the current list of updates and clear the list before iterating
488 lock (m_updateList)
489 {
490 updates = new List<SceneObjectGroup>(m_updateList.Values);
491 m_updateList.Clear();
492 }
493
494 // Go through all updates
495 for (int i = 0; i < updates.Count; i++)
496 { 467 {
497 SceneObjectGroup sog = updates[i]; 468 List<SceneObjectGroup> updates;
498 469
499 // Don't abort the whole update if one entity happens to give us an exception. 470 // Some updates add more updates to the updateList.
500 try 471 // Get the current list of updates and clear the list before iterating
472 lock (m_updateList)
501 { 473 {
502 sog.Update(); 474 updates = new List<SceneObjectGroup>(m_updateList.Values);
475 m_updateList.Clear();
503 } 476 }
504 catch (Exception e) 477
478 // Go through all updates
479 for (int i = 0; i < updates.Count; i++)
505 { 480 {
506 m_log.ErrorFormat( 481 SceneObjectGroup sog = updates[i];
507 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e); 482
483 // Don't abort the whole update if one entity happens to give us an exception.
484 try
485 {
486 sog.Update();
487 }
488 catch (Exception e)
489 {
490 m_log.ErrorFormat(
491 "[INNER SCENE]: Failed to update {0}, {1} - {2}", sog.Name, sog.UUID, e);
492 }
508 } 493 }
509 } 494 }
510 Monitor.Exit(m_updateLock); 495 finally
496 {
497 Monitor.Exit(m_updateLock);
498 }
511 } 499 }
512 500
513 protected internal void AddPhysicalPrim(int number) 501 protected internal void AddPhysicalPrim(int number)
@@ -864,8 +852,9 @@ namespace OpenSim.Region.Framework.Scenes
864 /// <returns>null if no scene object group containing that prim is found</returns> 852 /// <returns>null if no scene object group containing that prim is found</returns>
865 public SceneObjectGroup GetGroupByPrim(uint localID) 853 public SceneObjectGroup GetGroupByPrim(uint localID)
866 { 854 {
867 if (Entities.ContainsKey(localID)) 855 EntityBase entity;
868 return Entities[localID] as SceneObjectGroup; 856 if (Entities.TryGetValue(localID, out entity))
857 return entity as SceneObjectGroup;
869 858
870 //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID); 859 //m_log.DebugFormat("Entered GetGroupByPrim with localID {0}", localID);
871 SceneObjectGroup sog; 860 SceneObjectGroup sog;
@@ -879,23 +868,22 @@ namespace OpenSim.Region.Framework.Scenes
879 } 868 }
880 } 869 }
881 870
882 List<EntityBase> EntityList = GetEntities(); 871 EntityBase[] entityList = GetEntities();
883 foreach (EntityBase ent in EntityList) 872 foreach (EntityBase ent in entityList)
884 { 873 {
885 //m_log.DebugFormat("Looking at entity {0}", ent.UUID); 874 //m_log.DebugFormat("Looking at entity {0}", ent.UUID);
886 if (ent is SceneObjectGroup) 875 if (ent is SceneObjectGroup)
887 { 876 {
888 if (((SceneObjectGroup)ent).HasChildPrim(localID)) 877 sog = (SceneObjectGroup)ent;
878 if (sog.HasChildPrim(localID))
889 { 879 {
890 sog = (SceneObjectGroup)ent;
891 lock (SceneObjectGroupsByLocalID) 880 lock (SceneObjectGroupsByLocalID)
892 {
893 SceneObjectGroupsByLocalID[localID] = sog; 881 SceneObjectGroupsByLocalID[localID] = sog;
894 }
895 return sog; 882 return sog;
896 } 883 }
897 } 884 }
898 } 885 }
886
899 return null; 887 return null;
900 } 888 }
901 889
@@ -921,23 +909,21 @@ namespace OpenSim.Region.Framework.Scenes
921 } 909 }
922 } 910 }
923 911
924 List<EntityBase> EntityList = GetEntities(); 912 EntityBase[] entityList = GetEntities();
925 913 foreach (EntityBase ent in entityList)
926 foreach (EntityBase ent in EntityList)
927 { 914 {
928 if (ent is SceneObjectGroup) 915 if (ent is SceneObjectGroup)
929 { 916 {
930 if (((SceneObjectGroup)ent).HasChildPrim(fullID)) 917 sog = (SceneObjectGroup)ent;
918 if (sog.HasChildPrim(fullID))
931 { 919 {
932 sog = (SceneObjectGroup)ent;
933 lock (SceneObjectGroupsByFullID) 920 lock (SceneObjectGroupsByFullID)
934 {
935 SceneObjectGroupsByFullID[fullID] = sog; 921 SceneObjectGroupsByFullID[fullID] = sog;
936 }
937 return sog; 922 return sog;
938 } 923 }
939 } 924 }
940 } 925 }
926
941 return null; 927 return null;
942 } 928 }
943 929
@@ -946,7 +932,7 @@ namespace OpenSim.Region.Framework.Scenes
946 // Primitive Ray Tracing 932 // Primitive Ray Tracing
947 float closestDistance = 280f; 933 float closestDistance = 280f;
948 EntityIntersection result = new EntityIntersection(); 934 EntityIntersection result = new EntityIntersection();
949 List<EntityBase> EntityList = GetEntities(); 935 EntityBase[] EntityList = GetEntities();
950 foreach (EntityBase ent in EntityList) 936 foreach (EntityBase ent in EntityList)
951 { 937 {
952 if (ent is SceneObjectGroup) 938 if (ent is SceneObjectGroup)
@@ -984,23 +970,28 @@ namespace OpenSim.Region.Framework.Scenes
984 /// <returns>null if the part was not found</returns> 970 /// <returns>null if the part was not found</returns>
985 protected internal SceneObjectPart GetSceneObjectPart(string name) 971 protected internal SceneObjectPart GetSceneObjectPart(string name)
986 { 972 {
987 List<EntityBase> EntityList = GetEntities(); 973 SceneObjectPart sop = null;
988 974
989 // FIXME: use a dictionary here 975 Entities.Find(
990 foreach (EntityBase ent in EntityList) 976 delegate(EntityBase entity)
991 {
992 if (ent is SceneObjectGroup)
993 { 977 {
994 foreach (SceneObjectPart p in ((SceneObjectGroup) ent).GetParts()) 978 if (entity is SceneObjectGroup)
995 { 979 {
996 if (p.Name == name) 980 foreach (SceneObjectPart p in ((SceneObjectGroup)entity).GetParts())
997 { 981 {
998 return p; 982 if (p.Name == name)
983 {
984 sop = p;
985 return true;
986 }
999 } 987 }
1000 } 988 }
989
990 return false;
1001 } 991 }
1002 } 992 );
1003 return null; 993
994 return sop;
1004 } 995 }
1005 996
1006 /// <summary> 997 /// <summary>
@@ -1021,7 +1012,7 @@ namespace OpenSim.Region.Framework.Scenes
1021 /// it 1012 /// it
1022 /// </summary> 1013 /// </summary>
1023 /// <returns></returns> 1014 /// <returns></returns>
1024 protected internal List<EntityBase> GetEntities() 1015 protected internal EntityBase[] GetEntities()
1025 { 1016 {
1026 return Entities.GetEntities(); 1017 return Entities.GetEntities();
1027 } 1018 }
@@ -1030,7 +1021,7 @@ namespace OpenSim.Region.Framework.Scenes
1030 { 1021 {
1031 Dictionary<uint, float> topScripts = new Dictionary<uint, float>(); 1022 Dictionary<uint, float> topScripts = new Dictionary<uint, float>();
1032 1023
1033 List<EntityBase> EntityList = GetEntities(); 1024 EntityBase[] EntityList = GetEntities();
1034 int limit = 0; 1025 int limit = 0;
1035 foreach (EntityBase ent in EntityList) 1026 foreach (EntityBase ent in EntityList)
1036 { 1027 {
@@ -1726,8 +1717,8 @@ namespace OpenSim.Region.Framework.Scenes
1726 UUID objid = UUID.Zero; 1717 UUID objid = UUID.Zero;
1727 SceneObjectPart obj = null; 1718 SceneObjectPart obj = null;
1728 1719
1729 List<EntityBase> EntityList = GetEntities(); 1720 EntityBase[] entityList = GetEntities();
1730 foreach (EntityBase ent in EntityList) 1721 foreach (EntityBase ent in entityList)
1731 { 1722 {
1732 if (ent is SceneObjectGroup) 1723 if (ent is SceneObjectGroup)
1733 { 1724 {