mirror of
https://github.com/TES3MP/openmw-tes3mp.git
synced 2025-01-19 22:23:51 +00:00
Avoid a rare but possible deadlock around mCollisionWorldMutex.
What happened is that the last handle to an Actor shared_ptr was a promoted weak_ptr. When the shared_ptr goes out of scope, the Actor dtor is invoked. That involves removing the Actor collision object after exclusively locking mCollisionWorldMutex. In this case, the lock was already held in the outter scope of the promoted weak_ptr. Reduce the scope of the mCollisionWorldMutex to never encompass the lifetime of a promoted weak_ptr.
This commit is contained in:
parent
dc82cb61f4
commit
9bc687e209
1 changed files with 6 additions and 4 deletions
|
@ -357,7 +357,6 @@ namespace MWPhysics
|
|||
{
|
||||
if (!mDeferAabbUpdate || immediate)
|
||||
{
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
updatePtrAabb(ptr);
|
||||
}
|
||||
else
|
||||
|
@ -410,7 +409,7 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsTaskScheduler::updateAabbs()
|
||||
{
|
||||
std::scoped_lock lock(mCollisionWorldMutex, mUpdateAabbMutex);
|
||||
std::scoped_lock lock(mUpdateAabbMutex);
|
||||
std::for_each(mUpdateAabb.begin(), mUpdateAabb.end(),
|
||||
[this](const std::weak_ptr<PtrHolder>& ptr) { updatePtrAabb(ptr); });
|
||||
mUpdateAabb.clear();
|
||||
|
@ -420,6 +419,7 @@ namespace MWPhysics
|
|||
{
|
||||
if (const auto p = ptr.lock())
|
||||
{
|
||||
std::scoped_lock lock(mCollisionWorldMutex);
|
||||
if (const auto actor = std::dynamic_pointer_cast<Actor>(p))
|
||||
{
|
||||
actor->updateCollisionObjectPosition();
|
||||
|
@ -451,9 +451,11 @@ namespace MWPhysics
|
|||
int job = 0;
|
||||
while (mRemainingSteps && (job = mNextJob.fetch_add(1, std::memory_order_relaxed)) < mNumJobs)
|
||||
{
|
||||
MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
if(const auto actor = mActorsFrameData[job].mActor.lock())
|
||||
{
|
||||
MaybeSharedLock lockColWorld(mCollisionWorldMutex, mThreadSafeBullet);
|
||||
MovementSolver::move(mActorsFrameData[job], mPhysicsDt, mCollisionWorld.get(), *mWorldFrameData);
|
||||
}
|
||||
}
|
||||
|
||||
mPostStepBarrier->wait();
|
||||
|
@ -478,13 +480,13 @@ namespace MWPhysics
|
|||
|
||||
void PhysicsTaskScheduler::updateActorsPositions()
|
||||
{
|
||||
std::unique_lock lock(mCollisionWorldMutex);
|
||||
for (auto& actorData : mActorsFrameData)
|
||||
{
|
||||
if(const auto actor = actorData.mActor.lock())
|
||||
{
|
||||
if (actor->setPosition(actorData.mPosition))
|
||||
{
|
||||
std::scoped_lock lock(mCollisionWorldMutex);
|
||||
actor->updateCollisionObjectPosition();
|
||||
mCollisionWorld->updateSingleAabb(actor->getCollisionObject());
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue