Restore defects list. In hindsight, the reason for this is becuase we can't remove the character whilst iterating over the list.

This commit also removes locking on OdeScene._characters since code is single threaded
0.7.2-post-fixes
Justin Clark-Casey (justincc) 2011-11-21 21:04:24 +00:00
parent 5c305494ae
commit bba4577d88
2 changed files with 112 additions and 92 deletions

View File

@ -868,11 +868,10 @@ namespace OpenSim.Region.Physics.OdePlugin
/// Called from Simulate /// Called from Simulate
/// This is the avatar's movement control + PID Controller /// This is the avatar's movement control + PID Controller
/// </summary> /// </summary>
/// <remarks> /// <param name="defects">The character will be added to this list if there is something wrong (non-finite
/// This routine will remove the character from the physics scene if it detects something wrong (non-finite
/// position or velocity). /// position or velocity).
/// </remarks> /// </param>
internal void Move() internal void Move(List<OdeCharacter> defects)
{ {
// no lock; for now it's only called from within Simulate() // no lock; for now it's only called from within Simulate()
@ -897,8 +896,7 @@ namespace OpenSim.Region.Physics.OdePlugin
"[ODE CHARACTER]: Avatar position of {0} for {1} is non-finite! Removing from physics scene.", "[ODE CHARACTER]: Avatar position of {0} for {1} is non-finite! Removing from physics scene.",
localPos, Name); localPos, Name);
_parent_scene.RemoveCharacter(this); defects.Add(this);
DestroyOdeStructures();
return; return;
} }
@ -1037,15 +1035,19 @@ namespace OpenSim.Region.Physics.OdePlugin
"[ODE CHARACTER]: Got a NaN force vector {0} in Move() for {1}. Removing character from physics scene.", "[ODE CHARACTER]: Got a NaN force vector {0} in Move() for {1}. Removing character from physics scene.",
vec, Name); vec, Name);
_parent_scene.RemoveCharacter(this); defects.Add(this);
DestroyOdeStructures();
return;
} }
} }
/// <summary> /// <summary>
/// Updates the reported position and velocity. This essentially sends the data up to ScenePresence. /// Updates the reported position and velocity. This essentially sends the data up to ScenePresence.
/// </summary> /// </summary>
internal void UpdatePositionAndVelocity() /// <param name="defects">The character will be added to this list if there is something wrong (non-finite
/// position or velocity).
/// </param>
internal void UpdatePositionAndVelocity(List<OdeCharacter> defects)
{ {
// no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit! // no lock; called from Simulate() -- if you call this from elsewhere, gotta lock or do Monitor.Enter/Exit!
d.Vector3 newPos; d.Vector3 newPos;
@ -1056,11 +1058,12 @@ namespace OpenSim.Region.Physics.OdePlugin
catch (NullReferenceException) catch (NullReferenceException)
{ {
bad = true; bad = true;
_parent_scene.RemoveCharacter(this); defects.Add(this);
DestroyOdeStructures();
newPos = new d.Vector3(_position.X, _position.Y, _position.Z); newPos = new d.Vector3(_position.X, _position.Y, _position.Z);
base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem! base.RaiseOutOfBounds(_position); // Tells ScenePresence that there's a problem!
m_log.WarnFormat("[ODE CHARACTER]: Avatar Null reference for Avatar {0}, physical actor {1}", Name, m_uuid); m_log.WarnFormat("[ODE CHARACTER]: Avatar Null reference for Avatar {0}, physical actor {1}", Name, m_uuid);
return;
} }
// kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!) // kluge to keep things in bounds. ODE lets dead avatars drift away (they should be removed!)
@ -1140,7 +1143,7 @@ namespace OpenSim.Region.Physics.OdePlugin
/// <summary> /// <summary>
/// Used internally to destroy the ODE structures associated with this character. /// Used internally to destroy the ODE structures associated with this character.
/// </summary> /// </summary>
private void DestroyOdeStructures() internal void DestroyOdeStructures()
{ {
// destroy avatar capsule and related ODE data // destroy avatar capsule and related ODE data
if (Amotor != IntPtr.Zero) if (Amotor != IntPtr.Zero)

View File

@ -189,7 +189,11 @@ namespace OpenSim.Region.Physics.OdePlugin
public d.TriCallback triCallback; public d.TriCallback triCallback;
public d.TriArrayCallback triArrayCallback; public d.TriArrayCallback triArrayCallback;
/// <summary>
/// Avatars in the physics scene.
/// </summary>
private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>(); private readonly HashSet<OdeCharacter> _characters = new HashSet<OdeCharacter>();
private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>(); private readonly HashSet<OdePrim> _prims = new HashSet<OdePrim>();
private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>(); private readonly HashSet<OdePrim> _activeprims = new HashSet<OdePrim>();
@ -251,6 +255,14 @@ namespace OpenSim.Region.Physics.OdePlugin
/// </remarks> /// </remarks>
public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>(); public Dictionary<IntPtr, PhysicsActor> actor_name_map = new Dictionary<IntPtr, PhysicsActor>();
/// <summary>
/// Defects list to remove characters that no longer have finite positions due to some other bug.
/// </summary>
/// <remarks>
/// Used repeatedly in Simulate() but initialized once here.
/// </remarks>
private readonly List<OdeCharacter> defects = new List<OdeCharacter>();
private bool m_NINJA_physics_joints_enabled = false; private bool m_NINJA_physics_joints_enabled = false;
//private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>(); //private Dictionary<String, IntPtr> jointpart_name_map = new Dictionary<String,IntPtr>();
private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>(); private readonly Dictionary<String, List<PhysicsJoint>> joints_connecting_actor = new Dictionary<String, List<PhysicsJoint>>();
@ -1512,8 +1524,6 @@ namespace OpenSim.Region.Physics.OdePlugin
{ {
_perloopContact.Clear(); _perloopContact.Clear();
lock (_characters)
{
foreach (OdeCharacter chr in _characters) foreach (OdeCharacter chr in _characters)
{ {
// Reset the collision values to false // Reset the collision values to false
@ -1551,7 +1561,6 @@ namespace OpenSim.Region.Physics.OdePlugin
//forcedZ = true; //forcedZ = true;
//} //}
} }
}
lock (_activeprims) lock (_activeprims)
{ {
@ -1715,8 +1724,6 @@ namespace OpenSim.Region.Physics.OdePlugin
} }
internal void AddCharacter(OdeCharacter chr) internal void AddCharacter(OdeCharacter chr)
{
lock (_characters)
{ {
if (!_characters.Contains(chr)) if (!_characters.Contains(chr))
{ {
@ -1726,11 +1733,8 @@ namespace OpenSim.Region.Physics.OdePlugin
m_log.ErrorFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid); m_log.ErrorFormat("[PHYSICS] Added BAD actor {0} to characters list", chr.m_uuid);
} }
} }
}
internal void RemoveCharacter(OdeCharacter chr) internal void RemoveCharacter(OdeCharacter chr)
{
lock (_characters)
{ {
if (_characters.Contains(chr)) if (_characters.Contains(chr))
{ {
@ -1739,7 +1743,6 @@ namespace OpenSim.Region.Physics.OdePlugin
actor_name_map.Remove(chr.Shell); actor_name_map.Remove(chr.Shell);
} }
} }
}
private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation, private PhysicsActor AddPrim(String name, Vector3 position, Vector3 size, Quaternion rotation,
PrimitiveBaseShape pbs, bool isphysical, uint localID) PrimitiveBaseShape pbs, bool isphysical, uint localID)
@ -2783,13 +2786,21 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
} }
// Move characters // Move characters
lock (_characters)
{
foreach (OdeCharacter actor in _characters) foreach (OdeCharacter actor in _characters)
{ {
if (actor != null) if (actor != null)
actor.Move(); actor.Move(defects);
} }
if (defects.Count != 0)
{
foreach (OdeCharacter actor in defects)
{
RemoveCharacter(actor);
actor.DestroyOdeStructures();
}
defects.Clear();
} }
// Move other active objects // Move other active objects
@ -2849,8 +2860,6 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
timeLeft -= ODE_STEPSIZE; timeLeft -= ODE_STEPSIZE;
} }
lock (_characters)
{
foreach (OdeCharacter actor in _characters) foreach (OdeCharacter actor in _characters)
{ {
if (actor != null) if (actor != null)
@ -2858,9 +2867,19 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
if (actor.bad) if (actor.bad)
m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid); m_log.WarnFormat("[PHYSICS]: BAD Actor {0} in _characters list was not removed?", actor.m_uuid);
actor.UpdatePositionAndVelocity(); actor.UpdatePositionAndVelocity(defects);
} }
} }
if (defects.Count != 0)
{
foreach (OdeCharacter actor in defects)
{
RemoveCharacter(actor);
actor.DestroyOdeStructures();
}
defects.Clear();
} }
lock (_activeprims) lock (_activeprims)
@ -3882,8 +3901,7 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
} }
} }
ds.SetColor(1.0f, 0.0f, 0.0f); ds.SetColor(1.0f, 0.0f, 0.0f);
lock (_characters)
{
foreach (OdeCharacter chr in _characters) foreach (OdeCharacter chr in _characters)
{ {
if (chr.Shell != IntPtr.Zero) if (chr.Shell != IntPtr.Zero)
@ -3908,7 +3926,6 @@ Console.WriteLine("AddPhysicsActorTaint to " + taintedprim.Name);
} }
} }
} }
}
public void start(int unused) public void start(int unused)
{ {