aboutsummaryrefslogtreecommitdiffstatshomepage
diff options
context:
space:
mode:
-rw-r--r--OpenSim/Region/Physics/OdePlugin/ODECharacter.cs3
-rw-r--r--OpenSim/Region/Physics/OdePlugin/OdeScene.cs30
2 files changed, 32 insertions, 1 deletions
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index c6e8286..7c1c046 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -1048,6 +1048,7 @@ namespace OpenSim.Region.Physics.OdePlugin
1048 CAPSULE_RADIUS = 0.01f; 1048 CAPSULE_RADIUS = 0.01f;
1049 } 1049 }
1050 1050
1051// lock (OdeScene.UniversalColliderSyncObject)
1051 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH); 1052 Shell = d.CreateCapsule(_parent_scene.space, CAPSULE_RADIUS, CAPSULE_LENGTH);
1052 1053
1053 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories); 1054 d.GeomSetCategoryBits(Shell, (int)m_collisionCategories);
@@ -1179,7 +1180,9 @@ namespace OpenSim.Region.Physics.OdePlugin
1179 1180
1180 if (Shell != IntPtr.Zero) 1181 if (Shell != IntPtr.Zero)
1181 { 1182 {
1183// lock (OdeScene.UniversalColliderSyncObject)
1182 d.GeomDestroy(Shell); 1184 d.GeomDestroy(Shell);
1185
1183 _parent_scene.geom_name_map.Remove(Shell); 1186 _parent_scene.geom_name_map.Remove(Shell);
1184 _parent_scene.actor_name_map.Remove(Shell); 1187 _parent_scene.actor_name_map.Remove(Shell);
1185 1188
diff --git a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
index 37daf46..4530c09 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdeScene.cs
@@ -105,6 +105,32 @@ namespace OpenSim.Region.Physics.OdePlugin
105 private readonly ILog m_log; 105 private readonly ILog m_log;
106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>(); 106 // private Dictionary<string, sCollisionData> m_storedCollisions = new Dictionary<string, sCollisionData>();
107 107
108 /// <summary>
109 /// Provide a sync object so that only one thread calls d.Collide() at a time across all OdeScene instances.
110 /// </summary>
111 /// <remarks>
112 /// With ODE as of r1755 (though also tested on r1860), only one thread can call d.Collide() at a
113 /// time, even where physics objects are in entirely different ODE worlds. This is because generating contacts
114 /// uses a static cache at the ODE level.
115 ///
116 /// Without locking, simulators running multiple regions will eventually crash with a native stack trace similar
117 /// to
118 ///
119 /// mono() [0x489171]
120 /// mono() [0x4d154f]
121 /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f6ded592c60]
122 /// .../opensim/bin/libode-x86_64.so(_ZN6Opcode11OBBCollider8_CollideEPKNS_14AABBNoLeafNodeE+0xd7a) [0x7f6dd822628a]
123 ///
124 /// ODE provides an experimental option to cache in thread local storage but compiling ODE with this option
125 /// causes OpenSimulator to immediately crash with a native stack trace similar to
126 ///
127 /// mono() [0x489171]
128 /// mono() [0x4d154f]
129 /// /lib/x86_64-linux-gnu/libpthread.so.0(+0xfc60) [0x7f03c9849c60]
130 /// .../opensim/bin/libode-x86_64.so(_Z12dCollideCCTLP6dxGeomS0_iP12dContactGeomi+0x92) [0x7f03b44bcf82]
131 /// </remarks>
132 internal static Object UniversalColliderSyncObject = new Object();
133
108 private Random fluidRandomizer = new Random(Environment.TickCount); 134 private Random fluidRandomizer = new Random(Environment.TickCount);
109 135
110 private const uint m_regionWidth = Constants.RegionSize; 136 private const uint m_regionWidth = Constants.RegionSize;
@@ -799,7 +825,9 @@ namespace OpenSim.Region.Physics.OdePlugin
799 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact)) 825 if (b1 != IntPtr.Zero && b2 != IntPtr.Zero && d.AreConnectedExcluding(b1, b2, d.JointType.Contact))
800 return; 826 return;
801 827
802 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf); 828 lock (OdeScene.UniversalColliderSyncObject)
829 count = d.Collide(g1, g2, contacts.Length, contacts, d.ContactGeom.SizeOf);
830
803 if (count > contacts.Length) 831 if (count > contacts.Length)
804 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length); 832 m_log.Error("[ODE SCENE]: Got " + count + " contacts when we asked for a maximum of " + contacts.Length);
805 } 833 }