Bläddra i källkod

Fixed race condition in narrow phase query (#702)

If a body is removed between the broad phase detecting an overlap and the narrow phase locking the body, callbacks may be called on a body that has already been removed (it will still be a valid body because otherwise the lock would have failed). We ensure that the callbacks can assume that the body is still in the broadphase. The collision collector cannot make this assumption (as before).
Jorrit Rouwe 1 år sedan
förälder
incheckning
22e58e1fea
1 ändrade filer med 6 tillägg och 6 borttagningar
  1. 6 6
      Jolt/Physics/Collision/NarrowPhaseQuery.cpp

+ 6 - 6
Jolt/Physics/Collision/NarrowPhaseQuery.cpp

@@ -40,7 +40,7 @@ bool NarrowPhaseQuery::CastRay(const RRayCast &inRay, RayCastResult &ioHit, cons
 			{
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 					const Body &body = lock.GetBody();
 
@@ -106,7 +106,7 @@ void NarrowPhaseQuery::CastRay(const RRayCast &inRay, const RayCastSettings &inR
 			{
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 					const Body &body = lock.GetBody();
 
@@ -169,7 +169,7 @@ void NarrowPhaseQuery::CollidePoint(RVec3Arg inPoint, CollidePointCollector &ioC
 			{
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 					const Body &body = lock.GetBody();
 
@@ -235,7 +235,7 @@ void NarrowPhaseQuery::CollideShape(const Shape *inShape, Vec3Arg inShapeScale,
 			{
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 					const Body &body = lock.GetBody();
 
@@ -309,7 +309,7 @@ void NarrowPhaseQuery::CastShape(const RShapeCast &inShapeCast, const ShapeCastS
 			{
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult.mBodyID);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 					const Body &body = lock.GetBody();
 
@@ -371,7 +371,7 @@ void NarrowPhaseQuery::CollectTransformedShapes(const AABox &inBox, TransformedS
 			{
 				// Lock the body
 				BodyLockRead lock(mBodyLockInterface, inResult);
-				if (lock.Succeeded())
+				if (lock.SucceededAndIsInBroadPhase()) // Race condition: body could have been removed since it has been found in the broadphase, ensures body is in the broadphase while we call the callbacks
 				{
 					const Body &body = lock.GetBody();