From 4241eb9c2cec0d525bf0b3ff5ea2c616268e65cf Mon Sep 17 00:00:00 2001 From: amzn-sean <75276488+amzn-sean@users.noreply.github.com> Date: Wed, 9 Jun 2021 17:42:16 +0100 Subject: [PATCH] fix crash in ragdoll (#1210) --- .../Source/PhysXCharacters/API/Ragdoll.cpp | 22 ++++++++++++++++--- .../Code/Source/PhysXCharacters/API/Ragdoll.h | 2 ++ 2 files changed, 21 insertions(+), 3 deletions(-) diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.cpp b/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.cpp index 02ebe7281c..4725212a9d 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.cpp +++ b/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.cpp @@ -13,6 +13,7 @@ #include #include #include +#include #include #include #include @@ -40,6 +41,8 @@ namespace PhysX } // namespace Internal // PhysX::Ragdoll + /*static*/ AZStd::mutex Ragdoll::m_sceneEventMutex; + void Ragdoll::Reflect(AZ::ReflectContext* context) { AZ::SerializeContext* serializeContext = azrtti_cast(context); @@ -114,7 +117,10 @@ namespace PhysX Ragdoll::~Ragdoll() { - m_sceneStartSimHandler.Disconnect(); + { + AZStd::scoped_lock lock(m_sceneEventMutex); + m_sceneStartSimHandler.Disconnect(); + } m_nodes.clear(); //the nodes destructor will remove the simulated body from the scene. } @@ -212,7 +218,13 @@ namespace PhysX } } - sceneInterface->RegisterSceneSimulationStartHandler(m_sceneOwner, m_sceneStartSimHandler); + // the handler is also connected in EnableSimulationQueued(), + // which will call this function, so if called from that path dont connect here. + if (!m_sceneStartSimHandler.IsConnected()) + { + AZStd::scoped_lock lock(m_sceneEventMutex); + sceneInterface->RegisterSceneSimulationStartHandler(m_sceneOwner, m_sceneStartSimHandler); + } sceneInterface->EnableSimulationOfBody(m_sceneOwner, m_bodyHandle); } @@ -225,6 +237,7 @@ namespace PhysX if (auto* sceneInterface = AZ::Interface::Get()) { + AZStd::scoped_lock lock(m_sceneEventMutex); sceneInterface->RegisterSceneSimulationStartHandler(m_sceneOwner, m_sceneStartSimHandler); } @@ -244,7 +257,10 @@ namespace PhysX return; } - m_sceneStartSimHandler.Disconnect(); + { + AZStd::scoped_lock lock(m_sceneEventMutex); + m_sceneStartSimHandler.Disconnect(); + } physx::PxScene* pxScene = Internal::GetPxScene(m_sceneOwner); const size_t numNodes = m_nodes.size(); diff --git a/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.h b/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.h index 7182a3a44c..006ce5878b 100644 --- a/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.h +++ b/Gems/PhysX/Code/Source/PhysXCharacters/API/Ragdoll.h @@ -12,6 +12,7 @@ #pragma once +#include #include #include #include @@ -84,5 +85,6 @@ namespace PhysX bool m_queuedDisableSimulation = false; AzPhysics::SceneEvents::OnSceneSimulationStartHandler m_sceneStartSimHandler; + static AZStd::mutex m_sceneEventMutex; }; } // namespace PhysX