From 5988f8cce68844e038a469e57cfd37c39ff6a2c7 Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 24 May 2019 16:12:01 -0700 Subject: [PATCH 1/2] avoid calling removeOwnershipData() from multiple threads --- interface/src/Application.cpp | 1 + libraries/physics/src/PhysicalEntitySimulation.cpp | 14 ++++++++++++-- libraries/physics/src/PhysicalEntitySimulation.h | 2 ++ 3 files changed, 15 insertions(+), 2 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index a0cb790958..64cf375c25 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -6401,6 +6401,7 @@ void Application::update(float deltaTime) { PerformanceTimer perfTimer("simulation"); getEntities()->preUpdate(); + _entitySimulation->removeDeadEntities(); auto t0 = std::chrono::high_resolution_clock::now(); auto t1 = t0; diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 3c730fc6cf..98d4e993bf 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -218,11 +218,21 @@ void PhysicalEntitySimulation::clearEntitiesInternal() { // virtual void PhysicalEntitySimulation::prepareEntityForDelete(EntityItemPointer entity) { + // this can be called on any thread assert(entity); assert(entity->isDead()); QMutexLocker lock(&_mutex); - entity->clearActions(getThisPointer()); - removeEntityInternal(entity); + _entitiesToDeleteLater.push_back(entity); +} + +void PhysicalEntitySimulation::removeDeadEntities() { + // only ever call this on the main thread + QMutexLocker lock(&_mutex); + for (auto& entity : _entitiesToDeleteLater) { + entity->clearActions(getThisPointer()); + removeEntityInternal(entity); + } + _entitiesToDeleteLater.clear(); } // end EntitySimulation overrides diff --git a/libraries/physics/src/PhysicalEntitySimulation.h b/libraries/physics/src/PhysicalEntitySimulation.h index 817f92cb3c..f5213f7fef 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.h +++ b/libraries/physics/src/PhysicalEntitySimulation.h @@ -80,6 +80,7 @@ protected: // only called by EntitySimulation public: virtual void prepareEntityForDelete(EntityItemPointer entity) override; + void removeDeadEntities(); void buildPhysicsTransaction(PhysicsEngine::Transaction& transaction); void handleProcessedPhysicsTransaction(PhysicsEngine::Transaction& transaction); @@ -121,6 +122,7 @@ private: VectorOfEntityMotionStates _owned; VectorOfEntityMotionStates _bids; SetOfEntities _deadAvatarEntities; + std::vector _entitiesToDeleteLater; workload::SpacePointer _space; uint64_t _nextBidExpiry; uint32_t _lastStepSendPackets { 0 }; From a6a877d930c50d68c2e6931ca15a9645cb399c5c Mon Sep 17 00:00:00 2001 From: Andrew Meadows Date: Fri, 24 May 2019 16:17:55 -0700 Subject: [PATCH 2/2] clear _entitiesToDeleteLater on shutdown --- libraries/physics/src/PhysicalEntitySimulation.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/libraries/physics/src/PhysicalEntitySimulation.cpp b/libraries/physics/src/PhysicalEntitySimulation.cpp index 98d4e993bf..7bbf1854fa 100644 --- a/libraries/physics/src/PhysicalEntitySimulation.cpp +++ b/libraries/physics/src/PhysicalEntitySimulation.cpp @@ -214,6 +214,7 @@ void PhysicalEntitySimulation::clearEntitiesInternal() { _entitiesToRemoveFromPhysics.clear(); _entitiesToAddToPhysics.clear(); _incomingChanges.clear(); + _entitiesToDeleteLater.clear(); } // virtual