From 3588d89b2cba36415991c46c300b1f9c94f109bf Mon Sep 17 00:00:00 2001
From: Teravus Ovares
Date: Wed, 13 Feb 2008 23:14:41 +0000
Subject: * Bigish ODE stability Update.  Run Prebuild

---
 .../Region/Communications/OGS1/OGS1GridServices.cs | 131 +++++++-----
 .../BasicPhysicsPlugin/BasicPhysicsPlugin.cs       |   4 +
 .../Region/Physics/BulletXPlugin/BulletXPlugin.cs  |   5 +
 OpenSim/Region/Physics/Manager/CollisionLocker.cs  |  46 ++++
 OpenSim/Region/Physics/Manager/PhysicsActor.cs     |   7 +
 OpenSim/Region/Physics/OdePlugin/ODECharacter.cs   |  12 +-
 OpenSim/Region/Physics/OdePlugin/ODEPrim.cs        | 238 +++++++++++++--------
 OpenSim/Region/Physics/OdePlugin/OdePlugin.cs      |  96 ++++++---
 OpenSim/Region/Physics/POSPlugin/POSPlugin.cs      |   8 +
 OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs  |   8 +
 10 files changed, 380 insertions(+), 175 deletions(-)
 create mode 100644 OpenSim/Region/Physics/Manager/CollisionLocker.cs

(limited to 'OpenSim')

diff --git a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
index f8ab9ef..1953140 100644
--- a/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
+++ b/OpenSim/Region/Communications/OGS1/OGS1GridServices.cs
@@ -825,77 +825,92 @@ namespace OpenSim.Region.Communications.OGS1
         /// <returns></returns>
         public bool InformRegionOfPrimCrossing(ulong regionHandle, LLUUID primID, string objData)
         {
-            RegionInfo regInfo = null;
-            try
+             int failures = 0;
+            lock (m_deadRegionCache)
             {
-                if (m_localBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData))
+                if (m_deadRegionCache.ContainsKey(regionHandle))
                 {
-                    return true;
+                    failures = m_deadRegionCache[regionHandle];
                 }
-
-                regInfo = RequestNeighbourInfo(regionHandle);
-                if (regInfo != null)
+            }
+            if (failures <= 3)
+            {
+                RegionInfo regInfo = null;
+                try
                 {
-                    //don't want to be creating a new link to the remote instance every time like we are here
-                    bool retValue = false;
-
-
-                    OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting) Activator.GetObject(
-                                                                                      typeof (OGS1InterRegionRemoting),
-                                                                                      "tcp://" + regInfo.RemotingAddress +
-                                                                                      ":" + regInfo.RemotingPort +
-                                                                                      "/InterRegions");
-
-                    if (remObject != null)
+                    if (m_localBackend.InformRegionOfPrimCrossing(regionHandle, primID, objData))
                     {
-                        retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.UUID, objData);
+                        return true;
                     }
-                    else
+
+                    regInfo = RequestNeighbourInfo(regionHandle);
+                    if (regInfo != null)
                     {
-                        Console.WriteLine("remoting object not found");
-                    }
-                    remObject = null;
+                        //don't want to be creating a new link to the remote instance every time like we are here
+                        bool retValue = false;
 
 
-                    return retValue;
+                        OGS1InterRegionRemoting remObject = (OGS1InterRegionRemoting)Activator.GetObject(
+                                                                                          typeof(OGS1InterRegionRemoting),
+                                                                                          "tcp://" + regInfo.RemotingAddress +
+                                                                                          ":" + regInfo.RemotingPort +
+                                                                                          "/InterRegions");
+
+                        if (remObject != null)
+                        {
+                            retValue = remObject.InformRegionOfPrimCrossing(regionHandle, primID.UUID, objData);
+                        }
+                        else
+                        {
+                            Console.WriteLine("remoting object not found");
+                        }
+                        remObject = null;
+
+
+                        return retValue;
+                    }
+                    NoteDeadRegion(regionHandle);
+                    return false;
                 }
-                NoteDeadRegion(regionHandle);
-                return false;
-            }
-            catch (RemotingException e)
-            {
-                NoteDeadRegion(regionHandle);
-                m_log.Warn("Remoting Error: Unable to connect to adjacent region: " + regionHandle);
-                m_log.Debug(e.ToString());
-                return false;
-            }
-            catch (SocketException e)
-            {
-                NoteDeadRegion(regionHandle);
-                m_log.Warn("Remoting Error: Unable to connect to adjacent region: " + regionHandle);
-                m_log.Debug(e.ToString());
-                return false;
-            }
-            catch (InvalidCredentialException e)
-            {
-                NoteDeadRegion(regionHandle);
-                m_log.Warn("Invalid Credential Exception: Invalid Credentials : " + regionHandle);
-                m_log.Debug(e.ToString());
-                return false;
-            }
-            catch (AuthenticationException e)
-            {
-                NoteDeadRegion(regionHandle);
-                m_log.Warn("Authentication exception: Unable to connect to adjacent region: " + regionHandle);
+                catch (RemotingException e)
+                {
+                    NoteDeadRegion(regionHandle);
+                    m_log.Warn("Remoting Error: Unable to connect to adjacent region: " + regionHandle);
+                    m_log.Debug(e.ToString());
+                    return false;
+                }
+                catch (SocketException e)
+                {
+                    NoteDeadRegion(regionHandle);
+                    m_log.Warn("Remoting Error: Unable to connect to adjacent region: " + regionHandle);
+                    m_log.Debug(e.ToString());
+                    return false;
+                }
+                catch (InvalidCredentialException e)
+                {
+                    NoteDeadRegion(regionHandle);
+                    m_log.Warn("Invalid Credential Exception: Invalid Credentials : " + regionHandle);
+                    m_log.Debug(e.ToString());
+                    return false;
+                }
+                catch (AuthenticationException e)
+                {
+                    NoteDeadRegion(regionHandle);
+                    m_log.Warn("Authentication exception: Unable to connect to adjacent region: " + regionHandle);
 
-                m_log.Debug(e.ToString());
-                return false;
+                    m_log.Debug(e.ToString());
+                    return false;
+                }
+                catch (Exception e)
+                {
+                    NoteDeadRegion(regionHandle);
+                    m_log.Warn("Unknown exception: Unable to connect to adjacent region: " + regionHandle);
+                    m_log.Debug(e.ToString());
+                    return false;
+                }
             }
-            catch (Exception e)
+            else
             {
-                NoteDeadRegion(regionHandle);
-                m_log.Warn("Unknown exception: Unable to connect to adjacent region: " + regionHandle);
-                m_log.Debug(e.ToString());
                 return false;
             }
         }
diff --git a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
index b7ed417..a32bca5 100644
--- a/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
+++ b/OpenSim/Region/Physics/BasicPhysicsPlugin/BasicPhysicsPlugin.cs
@@ -351,5 +351,9 @@ namespace OpenSim.Region.Physics.BasicPhysicsPlugin
         public override void SetMomentum(PhysicsVector momentum)
         {
         }
+        public override void CrossingFailure()
+        {
+
+        }
     }
 }
\ No newline at end of file
diff --git a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
index 1080aa4..5a8589c 100644
--- a/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
+++ b/OpenSim/Region/Physics/BulletXPlugin/BulletXPlugin.cs
@@ -986,6 +986,11 @@ namespace OpenSim.Region.Physics.BulletXPlugin
         }
 
         #endregion
+
+        public override void CrossingFailure()
+        {
+
+        }
     }
 
     /// <summary>
diff --git a/OpenSim/Region/Physics/Manager/CollisionLocker.cs b/OpenSim/Region/Physics/Manager/CollisionLocker.cs
new file mode 100644
index 0000000..7a11720
--- /dev/null
+++ b/OpenSim/Region/Physics/Manager/CollisionLocker.cs
@@ -0,0 +1,46 @@
+using System;
+using System.Collections.Generic;
+using System.Text;
+
+namespace OpenSim.Region.Physics.Manager
+{
+    public class CollisionLocker
+    {
+        
+        private bool locked = false;
+        private List<IntPtr> worldlock = new List<IntPtr>();
+        public CollisionLocker()
+        {
+
+        }
+        public void dlock(IntPtr world)
+        {
+            lock (worldlock)
+            {
+                worldlock.Add(world);
+            }
+
+        }
+        public void dunlock(IntPtr world)
+        {
+            lock (worldlock)
+            {
+                worldlock.Remove(world);
+            }
+        }
+        public bool lockquery()
+        {
+            return (worldlock.Count > 0);
+        }
+        public void drelease(IntPtr world)
+        {
+            lock (worldlock)
+            {
+                if (worldlock.Contains(world))
+                    worldlock.Remove(world);
+            }
+        }
+
+    }
+
+}
diff --git a/OpenSim/Region/Physics/Manager/PhysicsActor.cs b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
index 7741687..97eccba 100644
--- a/OpenSim/Region/Physics/Manager/PhysicsActor.cs
+++ b/OpenSim/Region/Physics/Manager/PhysicsActor.cs
@@ -126,6 +126,8 @@ namespace OpenSim.Region.Physics.Manager
 
         public abstract bool Selected { set; }
 
+        public abstract void CrossingFailure();
+
         public virtual void RequestPhysicsterseUpdate()
         {
             // Make a temporary copy of the event to avoid possibility of
@@ -279,6 +281,11 @@ namespace OpenSim.Region.Physics.Manager
             get { return 0f; }
         }
 
+        public override void CrossingFailure()
+        {
+
+        }
+
 
         public override Quaternion Orientation
         {
diff --git a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
index 80c2a48..75d62cc 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODECharacter.cs
@@ -16,7 +16,7 @@
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DISCLAIMEd. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
@@ -35,7 +35,7 @@ using OpenSim.Region.Physics.Manager;
 namespace OpenSim.Region.Physics.OdePlugin
 {
     /// <summary>
-    /// Various properties that ODE uses for AMotors but isn't exposed in ODE.NET so we must define them ourselves.
+    /// Various properties that ODE uses for AMotors but isn't exposed in d.NET so we must define them ourselves.
     /// </summary>
  
     public enum dParam : int
@@ -87,6 +87,7 @@ namespace OpenSim.Region.Physics.OdePlugin
         private bool m_hackSentFall = false;
         private bool m_hackSentFly = false;
         private bool m_foundDebian = false;
+        private CollisionLocker ode;
 
         private string m_name = String.Empty;
 
@@ -103,8 +104,9 @@ namespace OpenSim.Region.Physics.OdePlugin
         public d.Mass ShellMass;
         public bool collidelock = false;
 
-        public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos)
+        public OdeCharacter(String avName, OdeScene parent_scene, PhysicsVector pos, CollisionLocker dode)
         {
+            ode = dode;
             _velocity = new PhysicsVector();
             _target_velocity = new PhysicsVector();
             _position = pos;
@@ -801,5 +803,9 @@ namespace OpenSim.Region.Physics.OdePlugin
                 d.BodyDestroy(Body);
             }
         }
+        public override void CrossingFailure()
+        {
+
+        }
     }
 }
diff --git a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
index 6103320..527a5cc 100644
--- a/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
+++ b/OpenSim/Region/Physics/OdePlugin/ODEPrim.cs
@@ -16,7 +16,7 @@
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DISCLAIMEd. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
@@ -56,6 +56,8 @@ namespace OpenSim.Region.Physics.OdePlugin
         public bool m_taintremove = false;
         public bool m_taintdisable = false;
         public bool m_disabled = false;
+        public bool m_taintadd = false;
+        private CollisionLocker ode;
 
         private bool m_taintforce = false;
         private List<PhysicsVector> m_forcelist = new List<PhysicsVector>();
@@ -74,6 +76,7 @@ namespace OpenSim.Region.Physics.OdePlugin
         public int m_interpenetrationcount = 0;
         public int m_collisionscore = 0;
         public int m_roundsUnderMotionThreshold = 0;
+        private int m_crossingfailures = 0;
 
         public bool outofBounds = false;
         private float m_density = 10.000006836f; // Aluminum g/cm3;
@@ -90,9 +93,9 @@ namespace OpenSim.Region.Physics.OdePlugin
         private int debugcounter = 0;
 
         public OdePrim(String primName, OdeScene parent_scene, IntPtr targetSpace, PhysicsVector pos, PhysicsVector size,
-                       Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical)
+                       Quaternion rotation, IMesh mesh, PrimitiveBaseShape pbs, bool pisPhysical, CollisionLocker dode)
         {
-           
+            ode = dode;
             _velocity = new PhysicsVector();
             _position = pos;
             m_taintposition = pos;
@@ -136,86 +139,11 @@ namespace OpenSim.Region.Physics.OdePlugin
                     m_targetSpace = _parent_scene.space;
             }
             m_primName = primName;
-            if (mesh != null)
-            {
-            }
-            else
-            {
-                if (_parent_scene.needsMeshing(_pbs))
-                {
-                    // Don't need to re-enable body..   it's done in SetMesh
-                    mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size);
-                    // createmesh returns null when it's a shape that isn't a cube.
-                }
-            }
-
-            lock (OdeScene.OdeLock)
-            {
-                if (mesh != null)
-                {
-                    setMesh(parent_scene, mesh);
-                }
-                else
-                {
-                    if (pbs.ProfileShape == ProfileShape.HalfCircle && pbs.PathCurve == (byte)Extrusion.Curve1)
-                    {
-                        if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
-                        {
-                            if (((_size.X / 2f) > 0f))
-                            {
-
-
-                                _parent_scene.waitForSpaceUnlock(m_targetSpace);
-                                prim_geom = d.CreateSphere(m_targetSpace, _size.X / 2);
-                            }
-                            else
-                            {
-                                _parent_scene.waitForSpaceUnlock(m_targetSpace);
-                                prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
-                            }
-                        }
-                        else
-                        {
-                            _parent_scene.waitForSpaceUnlock(m_targetSpace);
-                            prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
-                        }
-                    }
-                    //else if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
-                    //{
-                        //Cyllinder
-                        //if (_size.X == _size.Y)
-                        //{
-                            //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
-                        //}
-                        //else
-                        //{
-                            //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
-                        //}
-                    //}
-                    else
-                    {
-                        _parent_scene.waitForSpaceUnlock(m_targetSpace);
-                        prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
-                    }
-                }
-
-                d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
-                d.Quaternion myrot = new d.Quaternion();
-                myrot.W = rotation.w;
-                myrot.X = rotation.x;
-                myrot.Y = rotation.y;
-                myrot.Z = rotation.z;
-                d.GeomSetQuaternion(prim_geom, ref myrot);
-
-
-                if (m_isphysical && Body == (IntPtr) 0)
-                {
-                    enableBody();
-                }
-                parent_scene.geom_name_map[prim_geom] = primName;
-                parent_scene.actor_name_map[prim_geom] = (PhysicsActor) this;
-                //  don't do .add() here; old geoms get recycled with the same hash
-            }
+            m_taintadd = true;
+            _parent_scene.AddPhysicsActorTaint(this);
+            //  don't do .add() here; old geoms get recycled with the same hash
+            parent_scene.geom_name_map[prim_geom] = primName;
+            parent_scene.actor_name_map[prim_geom] = (PhysicsActor) this;
         }
 
         /// <summary>
@@ -399,15 +327,18 @@ namespace OpenSim.Region.Physics.OdePlugin
 
         public void setMesh(OdeScene parent_scene, IMesh mesh)
         {
+            // This sleeper is there to moderate how long it takes between 
+            // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
+            
+            System.Threading.Thread.Sleep(10);
+            
             //Kill Body so that mesh can re-make the geom
             if (IsPhysical && Body != (IntPtr) 0)
             {
                 disableBody();
             }
 
-            // This sleeper is there to moderate how long it takes between 
-            // setting up the mesh and pre-processing it when we get rapid fire mesh requests on a single object
-            System.Threading.Thread.Sleep(10);
+
             
             
             float[] vertexList = mesh.getVertexListAsFloatLocked(); // Note, that vertextList is pinned in memory
@@ -448,6 +379,10 @@ namespace OpenSim.Region.Physics.OdePlugin
         public void ProcessTaints(float timestep)
         {
             System.Threading.Thread.Sleep(5);
+
+            if (m_taintadd)
+                changeadd(timestep);
+
             if (m_taintposition != _position)
                 Move(timestep);
 
@@ -477,8 +412,124 @@ namespace OpenSim.Region.Physics.OdePlugin
                 changevelocity(timestep);
         }
 
-        
 
+        public void changeadd(float timestep)
+        {
+            if (_mesh != null)
+            {
+            }
+            else
+            {
+                if (_parent_scene.needsMeshing(_pbs))
+                {
+                    // Don't need to re-enable body..   it's done in SetMesh
+                    _mesh = _parent_scene.mesher.CreateMesh(m_primName, _pbs, _size);
+                    // createmesh returns null when it's a shape that isn't a cube.
+                }
+            }
+
+            lock (OdeScene.OdeLock)
+            {
+                if (_mesh != null)
+                {
+                    setMesh(_parent_scene, _mesh);
+                }
+                else
+                {
+                    if (_pbs.ProfileShape == ProfileShape.HalfCircle && _pbs.PathCurve == (byte)Extrusion.Curve1)
+                    {
+                        if (_size.X == _size.Y && _size.Y == _size.Z && _size.X == _size.Z)
+                        {
+                            if (((_size.X / 2f) > 0f))
+                            {
+
+
+                                _parent_scene.waitForSpaceUnlock(m_targetSpace);
+                                try
+                                {
+                                    prim_geom = d.CreateSphere(m_targetSpace, _size.X / 2);
+                                }
+                                catch (System.AccessViolationException)
+                                {
+                                    m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
+                                    return;
+                                }
+                            }
+                            else
+                            {
+                                _parent_scene.waitForSpaceUnlock(m_targetSpace);
+                                try
+                                {
+                                    prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+                                }
+                                catch (System.AccessViolationException)
+                                {
+                                    m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
+                                    return;
+                                }
+                            }
+                        }
+                        else
+                        {
+                            _parent_scene.waitForSpaceUnlock(m_targetSpace);
+                            try
+                            {
+                                prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+                            }
+                            catch (System.AccessViolationException)
+                            {
+                                return;
+                                m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
+                            }
+                        }
+                    }
+                    //else if (pbs.ProfileShape == ProfileShape.Circle && pbs.PathCurve == (byte)Extrusion.Straight)
+                    //{
+                    //Cyllinder
+                    //if (_size.X == _size.Y)
+                    //{
+                    //prim_geom = d.CreateCylinder(m_targetSpace, _size.X / 2, _size.Z);
+                    //}
+                    //else
+                    //{
+                    //prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+                    //}
+                    //}
+                    else
+                    {
+                        _parent_scene.waitForSpaceUnlock(m_targetSpace);
+                        try
+                        {
+                            prim_geom = d.CreateBox(m_targetSpace, _size.X, _size.Y, _size.Z);
+                        }
+                        catch (System.AccessViolationException)
+                        {
+                            m_log.Warn("[PHYSICS]: Unable to create physics proxy for object");
+                            return;
+                        }
+                    }
+                }
+
+                d.GeomSetPosition(prim_geom, _position.X, _position.Y, _position.Z);
+                d.Quaternion myrot = new d.Quaternion();
+                myrot.W = _orientation.w;
+                myrot.X = _orientation.x;
+                myrot.Y = _orientation.y;
+                myrot.Z = _orientation.z;
+                d.GeomSetQuaternion(prim_geom, ref myrot);
+
+
+                if (m_isphysical && Body == (IntPtr)0)
+                {
+                    enableBody();
+                }
+
+
+            }
+            m_taintadd = false;
+
+
+        }
         public void Move(float timestep)
         {
             if (m_isphysical)
@@ -941,7 +992,15 @@ namespace OpenSim.Region.Physics.OdePlugin
             }
             set { m_rotationalVelocity = value; }
         }
+        public override void CrossingFailure()
+        {
+            m_crossingfailures++;
+            if (m_crossingfailures >= 5)
+            {
+                m_log.Warn("[PHYSICS]: Too many crossing failures for: " + m_primName);
 
+            }
+        }
         public void UpdatePositionAndVelocity()
         {
             //  no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
@@ -969,7 +1028,10 @@ namespace OpenSim.Region.Physics.OdePlugin
 
                 if (l_position.X > 257f || l_position.X < -1f || l_position.Y > 257f || l_position.Y < -1f)
                 {
-                    base.RequestPhysicsterseUpdate();
+                    if (m_crossingfailures < 5)
+                    {
+                        base.RequestPhysicsterseUpdate();
+                    }
                 }
 
                 if (l_position.Z < 0)
diff --git a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
index 1c16cfb..66af095 100644
--- a/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
+++ b/OpenSim/Region/Physics/OdePlugin/OdePlugin.cs
@@ -16,7 +16,7 @@
 * THIS SOFTWARE IS PROVIDED BY THE DEVELOPERS ``AS IS'' AND ANY
 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED
 * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
-* DISCLAIMED. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
+* DISCLAIMEd. IN NO EVENT SHALL THE CONTRIBUTORS BE LIABLE FOR ANY
 * DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES
 * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
 * LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
@@ -46,10 +46,12 @@ namespace OpenSim.Region.Physics.OdePlugin
     {
         private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 
+        private CollisionLocker ode;
         private OdeScene _mScene;
 
         public OdePlugin()
         {
+            ode = new CollisionLocker();
         }
 
         public bool Init()
@@ -61,7 +63,7 @@ namespace OpenSim.Region.Physics.OdePlugin
         {
             if (_mScene == null)
             {
-                _mScene = new OdeScene();
+                _mScene = new OdeScene(ode);
             }
             return (_mScene);
         }
@@ -74,7 +76,7 @@ namespace OpenSim.Region.Physics.OdePlugin
         public void Dispose()
         {
             
-            d.CloseODE();
+            
         }
     }
 
@@ -82,6 +84,7 @@ namespace OpenSim.Region.Physics.OdePlugin
     {
         private static readonly log4net.ILog m_log = log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType);
 
+        CollisionLocker ode;
         // TODO: this should be hard-coded in some common place
         private const uint m_regionWidth = 256;
         private const uint m_regionHeight = 256;
@@ -137,8 +140,9 @@ namespace OpenSim.Region.Physics.OdePlugin
         /// Sets many properties that ODE requires to be stable
         /// These settings need to be tweaked 'exactly' right or weird stuff happens.
         /// </summary>
-        public OdeScene()
+        public OdeScene(CollisionLocker dode)
         {
+            ode = dode;
             nearCallback = near;
             triCallback = TriCallback;
             triArrayCallback = TriArrayCallback;
@@ -178,6 +182,7 @@ namespace OpenSim.Region.Physics.OdePlugin
 
             lock (OdeLock)
             {
+
                 // Creat the world and the first space
                 world = d.WorldCreate();
                 space = d.HashSpaceCreate(IntPtr.Zero);
@@ -268,8 +273,14 @@ namespace OpenSim.Region.Physics.OdePlugin
                 // We'll be calling near recursivly if one 
                 // of them is a space to find all of the 
                 // contact points in the space
-
-                d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
+                try
+                {
+                    d.SpaceCollide2(g1, g2, IntPtr.Zero, nearCallback);
+                }
+                catch (System.AccessViolationException)
+                {
+                    m_log.Warn("[PHYSICS]: Unable to collide test a space");
+                }
                 //Colliding a space or a geom with a space or a geom. so drill down
 
                 //Collide all geoms in each space..   
@@ -304,7 +315,7 @@ namespace OpenSim.Region.Physics.OdePlugin
                     name2 = "null";
                 }
 
-                //if (id == d.GeomClassID.TriMeshClass)
+                //if (id == d.GeomClassId.TriMeshClass)
                 //{
                     //               m_log.Info("near: A collision was detected between {1} and {2}", 0, name1, name2);
                     //System.Console.WriteLine("near: A collision was detected between {1} and {2}", 0, name1, name2);
@@ -321,6 +332,10 @@ namespace OpenSim.Region.Physics.OdePlugin
                     m_log.Error("[PHYSICS]: The Operating system shut down ODE because of corrupt memory.  This could be a result of really irregular terrain.  If this repeats continuously, restart using Basic Physics and terrain fill your terrain.  Restarting the sim.");
                     base.TriggerPhysicsBasedRestart();
                 }
+                catch (System.AccessViolationException)
+                {
+                    m_log.Warn("[PHYSICS]: Unable to collide test an object");
+                }
 
                 PhysicsActor p1;
                 PhysicsActor p2;
@@ -438,7 +453,7 @@ namespace OpenSim.Region.Physics.OdePlugin
                            
                             if (contacts[i].depth >= 0.25f)
                             {
-                                // Don't collide, one or both prim will explode.
+                                // Don't collide, one or both prim will expld.
                                 
 
                                 op1.m_interpenetrationcount++;
@@ -596,8 +611,14 @@ namespace OpenSim.Region.Physics.OdePlugin
                 // And we'll run this again against the avatar and the space segment
                 // This will return with a bunch of possible objects in the space segment
                 // and we'll run it again on all of them.
-
-                d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
+                try
+                {
+                    d.SpaceCollide2(space, chr.Shell, IntPtr.Zero, nearCallback);
+                }
+                catch (AccessViolationException)
+                {
+                    m_log.Warn("[PHYSICS]: Unable to space collide");
+                }
                 //float terrainheight = GetTerrainHeightAtXY(chr.Position.X, chr.Position.Y);
                 //if (chr.Position.Z + (chr.Velocity.Z * timeStep) < terrainheight + 10)
                 //{
@@ -616,8 +637,14 @@ namespace OpenSim.Region.Physics.OdePlugin
                     // This if may not need to be there..    it might be skipped anyway.
                     if (d.BodyIsEnabled(chr.Body) && (!chr.m_disabled))
                     {
-                        
-                        d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback);
+                        try 
+                        {
+                            d.SpaceCollide2(space, chr.prim_geom, IntPtr.Zero, nearCallback);
+                        }
+                        catch (AccessViolationException)
+                        {
+                            m_log.Warn("[PHYSICS]: Unable to space collide");
+                        }
                         //calculateSpaceForGeom(chr.Position)
                         //foreach (OdePrim ch2 in _prims)
                         /// should be a separate space -- lots of avatars will be N**2 slow
@@ -634,7 +661,14 @@ namespace OpenSim.Region.Physics.OdePlugin
                         //}
                         //}
                     }
-                    d.SpaceCollide2(LandGeom, chr.prim_geom, IntPtr.Zero, nearCallback);
+                    try 
+                    {
+                        d.SpaceCollide2(LandGeom, chr.prim_geom, IntPtr.Zero, nearCallback);
+                    }
+                    catch (AccessViolationException)
+                    {
+                        m_log.Warn("[PHYSICS]: Unable to space collide");
+                    }
                 }
             }
             else
@@ -663,7 +697,7 @@ namespace OpenSim.Region.Physics.OdePlugin
             pos.X = position.X;
             pos.Y = position.Y;
             pos.Z = position.Z;
-            OdeCharacter newAv = new OdeCharacter(avName, this, pos);
+            OdeCharacter newAv = new OdeCharacter(avName, this, pos, ode);
             _characters.Add(newAv);
             return newAv;
         }
@@ -1007,7 +1041,7 @@ namespace OpenSim.Region.Physics.OdePlugin
             OdePrim newPrim;
             lock (OdeLock)
             {
-                newPrim = new OdePrim(name, this, targetspace, pos, siz, rot, mesh, pbs, isphysical);
+                newPrim = new OdePrim(name, this, targetspace, pos, siz, rot, mesh, pbs, isphysical, ode);
 
                 _prims.Add(newPrim);
             }
@@ -1203,8 +1237,15 @@ namespace OpenSim.Region.Physics.OdePlugin
                         actor.Move(timeStep);
                         actor.collidelock = true;
                     }
+                    
+                    ode.dlock(world);
 
                     collision_optimized(timeStep);
+
+                    
+
+                    ode.dunlock(world);
+                    
                     try
                     {
                         d.WorldQuickStep(world, ODE_STEPSIZE);
@@ -1228,25 +1269,28 @@ namespace OpenSim.Region.Physics.OdePlugin
                     actor.UpdatePositionAndVelocity();
                 }
 
-                bool processedtaints = false;
-                foreach (OdePrim prim in _taintedPrim)
+                if (!ode.lockquery())
                 {
-                    prim.ProcessTaints(timeStep);
-                    if (prim.m_taintremove)
+                    bool processedtaints = false;
+                    foreach (OdePrim prim in _taintedPrim)
                     {
-                        RemovePrimThreadLocked(prim);
-                    }
-                    processedtaints = true;
-                    prim.m_collisionscore = 0;
+                        prim.ProcessTaints(timeStep);
+                        if (prim.m_taintremove)
+                        {
+                            RemovePrimThreadLocked(prim);
+                        }
+                        processedtaints = true;
+                        prim.m_collisionscore = 0;
+                    }  
+                    if (processedtaints)
+                        _taintedPrim = new List<OdePrim>();
                 }
-
                 foreach (OdePrim prim in _activeprims)
                 {
                     prim.m_collisionscore = 0;
                 }
 
-                if (processedtaints)
-                    _taintedPrim = new List<OdePrim>();
+              
 
                 if (timeStep < 0.2f)
                 {
diff --git a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs
index 5b132cf..7652934 100644
--- a/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs
+++ b/OpenSim/Region/Physics/POSPlugin/POSPlugin.cs
@@ -480,6 +480,10 @@ namespace OpenSim.Region.Physics.POSPlugin
         public override void SetMomentum(PhysicsVector momentum)
         {
         }
+        public override void CrossingFailure()
+        {
+
+        }
     }
 
     public class POSPrim : PhysicsActor
@@ -640,6 +644,10 @@ namespace OpenSim.Region.Physics.POSPlugin
         {
             set { return; }
         }
+        public override void CrossingFailure()
+        {
+
+        }
 
     }
 }
\ No newline at end of file
diff --git a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
index ad18507..4a0467c 100644
--- a/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
+++ b/OpenSim/Region/Physics/PhysXPlugin/PhysXPlugin.cs
@@ -393,6 +393,10 @@ namespace OpenSim.Region.Physics.PhysXPlugin
             _position.Y = vec.Y;
             _position.Z = vec.Z;
         }
+        public override void CrossingFailure()
+        {
+
+        }
     }
 
 
@@ -577,5 +581,9 @@ namespace OpenSim.Region.Physics.PhysXPlugin
         {
             get { return PhysicsVector.Zero; }
         }
+        public override void CrossingFailure()
+        {
+
+        }
     }
 }
\ No newline at end of file
-- 
cgit v1.1