From fb8e8dcbce6b2ecbb8fbfe8278657260ac55e823 Mon Sep 17 00:00:00 2001
From: UbitUmarov
Date: Mon, 9 Jul 2012 13:25:17 +0100
Subject:  fix ODE dispose  plus minor clean. On regions restart ode.dispose
 seems  to be called with scene still calling simulation, that should be
 changed,  for now added a check for a valid world in ode simulation

---
 OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs | 58 ++++++++++++++++++------
 1 file changed, 43 insertions(+), 15 deletions(-)

(limited to 'OpenSim')

diff --git a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
index 4552f3f..5920838 100644
--- a/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
+++ b/OpenSim/Region/Physics/UbitOdePlugin/OdeScene.cs
@@ -268,7 +268,7 @@ namespace OpenSim.Region.Physics.OdePlugin
 
         public ContactData[] m_materialContactsData = new ContactData[8];
 
-        private readonly DoubleDictionary<Vector3, IntPtr, IntPtr> RegionTerrain = new DoubleDictionary<Vector3, IntPtr, IntPtr>();
+        private readonly Dictionary<Vector3, IntPtr> RegionTerrain = new Dictionary<Vector3, IntPtr>();
         private readonly Dictionary<IntPtr, float[]> TerrainHeightFieldHeights = new Dictionary<IntPtr, float[]>();
         private readonly Dictionary<IntPtr, GCHandle> TerrainHeightFieldHeightsHandlers = new Dictionary<IntPtr, GCHandle>();
        
@@ -1892,18 +1892,22 @@ namespace OpenSim.Region.Physics.OdePlugin
             lock (SimulationLock)
                 lock(OdeLock)
             {
+                if (world == IntPtr.Zero)
+                    return 0;
+
                 // adjust number of iterations per step
-                try
-                {
+
+//                try
+//                {
                     d.WorldSetQuickStepNumIterations(world, curphysiteractions);
-                }
+/*                }
                 catch (StackOverflowException)
                 {
                     m_log.Error("[PHYSICS]: The operating system wasn't able to allocate enough memory for the simulation.  Restarting the sim.");
 //                    ode.drelease(world);
                     base.TriggerPhysicsBasedRestart();
                 }
-
+*/
                 while (step_time > HalfOdeStep && nodeframes < 10) //limit number of steps so we don't say here for ever
                 {
                     try
@@ -2383,11 +2387,9 @@ namespace OpenSim.Region.Physics.OdePlugin
                 d.RFromAxisAndAngle(out R, v3.X, v3.Y, v3.Z, angle);
                 d.GeomSetRotation(GroundGeom, ref R);
                 d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0);
-                RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
-//                TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
+                RegionTerrain.Add(pOffset, GroundGeom);
                 TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);
-                TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler);
-               
+                TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler);             
             }
         }
 
@@ -2486,8 +2488,7 @@ namespace OpenSim.Region.Physics.OdePlugin
                 geom_name_map[GroundGeom] = "Terrain";
 
                 d.GeomSetPosition(GroundGeom, pOffset.X + (float)Constants.RegionSize * 0.5f, pOffset.Y + (float)Constants.RegionSize * 0.5f, 0);
-                RegionTerrain.Add(pOffset, GroundGeom, GroundGeom);
-                //                TerrainHeightFieldHeights.Add(GroundGeom, ODElandMap);
+                RegionTerrain.Add(pOffset, GroundGeom);
                 TerrainHeightFieldHeights.Add(GroundGeom, _heightmap);
                 TerrainHeightFieldHeightsHandlers.Add(GroundGeom, _heightmaphandler);
             }
@@ -2649,19 +2650,42 @@ namespace OpenSim.Region.Physics.OdePlugin
 
         public override void Dispose()
         {
-            m_rayCastManager.Dispose();
-            m_rayCastManager = null;
-
             lock (OdeLock)
             {
+                m_rayCastManager.Dispose();
+                m_rayCastManager = null;
+
                 lock (_prims)
                 {
+                    ChangesQueue.Clear();
                     foreach (OdePrim prm in _prims)
                     {
-                        RemovePrim(prm);
+                        prm.DoAChange(changes.Remove, null);
+                        _collisionEventPrim.Remove(prm);
                     }
+                    _prims.Clear();
                 }
 
+                OdeCharacter[] chtorem;
+                lock (_characters)
+                {
+                    chtorem = new OdeCharacter[_characters.Count];
+                    _characters.CopyTo(chtorem);
+                }
+
+                ChangesQueue.Clear();
+                foreach (OdeCharacter ch in chtorem)
+                    ch.DoAChange(changes.Remove, null);
+
+                               
+                foreach (IntPtr GroundGeom in RegionTerrain.Values)
+                {
+                    if (GroundGeom != IntPtr.Zero)
+                        d.GeomDestroy(GroundGeom);
+                }
+
+                RegionTerrain.Clear();
+
                 if (TerrainHeightFieldHeightsHandlers.Count > 0)
                 {
                     foreach (GCHandle gch in TerrainHeightFieldHeightsHandlers.Values)
@@ -2671,6 +2695,9 @@ namespace OpenSim.Region.Physics.OdePlugin
                     }
                 }
 
+                TerrainHeightFieldHeightsHandlers.Clear();
+                TerrainHeightFieldHeights.Clear();
+
                 if (WaterGeom != IntPtr.Zero)
                 {
                     d.GeomDestroy(WaterGeom);
@@ -2691,6 +2718,7 @@ namespace OpenSim.Region.Physics.OdePlugin
 
 
                 d.WorldDestroy(world);
+                world = IntPtr.Zero;
                 //d.CloseODE();
             }
         }
-- 
cgit v1.1