fixed Ragdoll component can crash on deactivate (#2834)

fixes #2650
The root of the crash was connecting/disconnecting to the AZ::Event SceneSimulationStart when not on the main thread, as that is not thread safe.

The connection/disconnection was originally handled from Enable/EnableQueued and Disable/DisabledQueued which can be called from other threads within EmotionFX. I've moved the connection/disconnection to the Constructor / destructor, as the handler is responsible for executing the queued enable/disable actions and it makes sense to have that connection happen external to the Enable/disable path.

Signed-off-by: amzn-sean 75276488+amzn-sean@users.noreply.github.com
This commit is contained in:
amzn-sean
2021-08-05 14:27:31 +01:00
committed by GitHub
parent 92a5fb6df2
commit 34afed6792
2 changed files with 5 additions and 26 deletions
@@ -36,9 +36,6 @@ namespace PhysX
}
} // namespace Internal
// PhysX::Ragdoll
/*static*/ AZStd::mutex Ragdoll::m_sceneEventMutex;
void Ragdoll::Reflect(AZ::ReflectContext* context)
{
AZ::SerializeContext* serializeContext = azrtti_cast<AZ::SerializeContext*>(context);
@@ -109,14 +106,15 @@ namespace PhysX
})
{
m_sceneOwner = sceneHandle;
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
{
sceneInterface->RegisterSceneSimulationStartHandler(m_sceneOwner, m_sceneStartSimHandler);
}
}
Ragdoll::~Ragdoll()
{
{
AZStd::scoped_lock lock(m_sceneEventMutex);
m_sceneStartSimHandler.Disconnect();
}
m_sceneStartSimHandler.Disconnect();
m_nodes.clear(); //the nodes destructor will remove the simulated body from the scene.
}
@@ -214,13 +212,6 @@ namespace PhysX
}
}
// 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);
}
@@ -231,12 +222,6 @@ namespace PhysX
return;
}
if (auto* sceneInterface = AZ::Interface<AzPhysics::SceneInterface>::Get())
{
AZStd::scoped_lock lock(m_sceneEventMutex);
sceneInterface->RegisterSceneSimulationStartHandler(m_sceneOwner, m_sceneStartSimHandler);
}
m_queuedInitialState = initialState;
}
@@ -253,11 +238,6 @@ namespace PhysX
return;
}
{
AZStd::scoped_lock lock(m_sceneEventMutex);
m_sceneStartSimHandler.Disconnect();
}
physx::PxScene* pxScene = Internal::GetPxScene(m_sceneOwner);
const size_t numNodes = m_nodes.size();
@@ -81,6 +81,5 @@ namespace PhysX
bool m_queuedDisableSimulation = false;
AzPhysics::SceneEvents::OnSceneSimulationStartHandler m_sceneStartSimHandler;
static AZStd::mutex m_sceneEventMutex;
};
} // namespace PhysX