Merge pull request #11225 from hyperlogic/bug-fix/simulation-deadlock-fix

Bug fix for deadlock between EntitySimulation and EntityItem locks.
This commit is contained in:
Chris Collins 2017-08-23 20:50:41 -07:00 committed by GitHub
commit 751440388a
3 changed files with 9 additions and 8 deletions

View file

@ -280,24 +280,24 @@ void EntitySimulation::moveSimpleKinematics(const quint64& now) {
} }
void EntitySimulation::addDynamic(EntityDynamicPointer dynamic) { void EntitySimulation::addDynamic(EntityDynamicPointer dynamic) {
QMutexLocker lock(&_mutex); QMutexLocker lock(&_dynamicsMutex);
_dynamicsToAdd += dynamic; _dynamicsToAdd += dynamic;
} }
void EntitySimulation::removeDynamic(const QUuid dynamicID) { void EntitySimulation::removeDynamic(const QUuid dynamicID) {
QMutexLocker lock(&_mutex); QMutexLocker lock(&_dynamicsMutex);
_dynamicsToRemove += dynamicID; _dynamicsToRemove += dynamicID;
} }
void EntitySimulation::removeDynamics(QList<QUuid> dynamicIDsToRemove) { void EntitySimulation::removeDynamics(QList<QUuid> dynamicIDsToRemove) {
QMutexLocker lock(&_mutex); QMutexLocker lock(&_dynamicsMutex);
foreach(QUuid uuid, dynamicIDsToRemove) { foreach(QUuid uuid, dynamicIDsToRemove) {
_dynamicsToRemove.insert(uuid); _dynamicsToRemove.insert(uuid);
} }
} }
void EntitySimulation::applyDynamicChanges() { void EntitySimulation::applyDynamicChanges() {
QMutexLocker lock(&_mutex); QMutexLocker lock(&_dynamicsMutex);
_dynamicsToAdd.clear(); _dynamicsToAdd.clear();
_dynamicsToRemove.clear(); _dynamicsToRemove.clear();
} }

View file

@ -105,6 +105,7 @@ protected:
SetOfEntities _simpleKinematicEntities; // entities undergoing non-colliding kinematic motion SetOfEntities _simpleKinematicEntities; // entities undergoing non-colliding kinematic motion
QList<EntityDynamicPointer> _dynamicsToAdd; QList<EntityDynamicPointer> _dynamicsToAdd;
QSet<QUuid> _dynamicsToRemove; QSet<QUuid> _dynamicsToRemove;
QMutex _dynamicsMutex { QMutex::Recursive };
protected: protected:
SetOfEntities _entitiesToDelete; // entities simulation decided needed to be deleted (EntityTree will actually delete) SetOfEntities _entitiesToDelete; // entities simulation decided needed to be deleted (EntityTree will actually delete)

View file

@ -348,8 +348,7 @@ void PhysicalEntitySimulation::addDynamic(EntityDynamicPointer dynamic) {
void PhysicalEntitySimulation::applyDynamicChanges() { void PhysicalEntitySimulation::applyDynamicChanges() {
QList<EntityDynamicPointer> dynamicsFailedToAdd; QList<EntityDynamicPointer> dynamicsFailedToAdd;
if (_physicsEngine) { if (_physicsEngine) {
// FIXME put fine grain locking into _physicsEngine QMutexLocker lock(&_dynamicsMutex);
QMutexLocker lock(&_mutex);
foreach(QUuid dynamicToRemove, _dynamicsToRemove) { foreach(QUuid dynamicToRemove, _dynamicsToRemove) {
_physicsEngine->removeDynamic(dynamicToRemove); _physicsEngine->removeDynamic(dynamicToRemove);
} }
@ -360,9 +359,10 @@ void PhysicalEntitySimulation::applyDynamicChanges() {
} }
} }
} }
// applyDynamicChanges will clear _dynamicsToRemove and _dynamicsToAdd
EntitySimulation::applyDynamicChanges();
} }
// applyDynamicChanges will clear _dynamicsToRemove and _dynamicsToAdd
EntitySimulation::applyDynamicChanges();
// put back the ones that couldn't yet be added // put back the ones that couldn't yet be added
foreach (EntityDynamicPointer dynamicFailedToAdd, dynamicsFailedToAdd) { foreach (EntityDynamicPointer dynamicFailedToAdd, dynamicsFailedToAdd) {
addDynamic(dynamicFailedToAdd); addDynamic(dynamicFailedToAdd);