Merge pull request #4918 from howard-stearns/anti-collision-deadlock

Fix collision deadlock
This commit is contained in:
Philip Rosedale 2015-05-20 13:56:39 -07:00
commit f843acb673
2 changed files with 5 additions and 12 deletions

View file

@ -2461,7 +2461,6 @@ void Application::update(float deltaTime) {
if (_physicsEngine.hasOutgoingChanges()) {
_entitySimulation.lock();
_entitySimulation.handleOutgoingChanges(_physicsEngine.getOutgoingChanges(), _physicsEngine.getSessionID());
_entitySimulation.handleCollisionEvents(_physicsEngine.getCollisionEvents());
_entitySimulation.unlock();
_physicsEngine.dumpStatsIfNecessary();
}
@ -2469,9 +2468,11 @@ void Application::update(float deltaTime) {
if (!_aboutToQuit) {
PerformanceTimer perfTimer("entities");
// NOTE: the _entities.update() call below will wait for lock
// Collision events (and their scripts) must not be handled when we're locked, above. (That would risk deadlock.)
_entitySimulation.handleCollisionEvents(_physicsEngine.getCollisionEvents());
// NOTE: the _entities.update() call below will wait for lock
// and will simulate entity motion (the EntityTree has been given an EntitySimulation).
_entities.update(); // update the models...
_entities.update(); // update the models...
}
{

View file

@ -1174,8 +1174,7 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
if (!_tree || _shuttingDown) {
return;
}
// Don't respond to small continuous contacts. It causes deadlocks when locking the entityTree.
// Note that any entity script is likely to Entities.getEntityProperties(), which locks the tree.
// Don't respond to small continuous contacts.
const float COLLISION_MINUMUM_PENETRATION = 0.005;
if ((collision.type != CONTACT_EVENT_TYPE_START) && (glm::length(collision.penetration) < COLLISION_MINUMUM_PENETRATION)) {
return;
@ -1183,16 +1182,9 @@ void EntityTreeRenderer::entityCollisionWithEntity(const EntityItemID& idA, cons
// See if we should play sounds
EntityTree* entityTree = static_cast<EntityTree*>(_tree);
if (!entityTree->tryLockForRead()) {
// I don't know why this can happen, but if it does,
// the consequences are a deadlock, so bail.
qCDebug(entitiesrenderer) << "NOTICE: skipping collision type " << collision.type << " penetration " << glm::length(collision.penetration);
return;
}
const QUuid& myNodeID = DependencyManager::get<NodeList>()->getSessionUUID();
playEntityCollisionSound(myNodeID, entityTree, idA, collision);
playEntityCollisionSound(myNodeID, entityTree, idB, collision);
entityTree->unlock();
// And now the entity scripts
QScriptValue entityScriptA = loadEntityScript(idA);