From dcd425a165802880321ea23a439c1854495c1159 Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Tue, 4 Oct 2016 10:56:44 -0700 Subject: [PATCH] Add an entityTree lock around the AvatarHoldAction::lateAvatarUpdate calls --- interface/src/avatar/MyAvatar.cpp | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/interface/src/avatar/MyAvatar.cpp b/interface/src/avatar/MyAvatar.cpp index 20c4f41568..19346e51db 100644 --- a/interface/src/avatar/MyAvatar.cpp +++ b/interface/src/avatar/MyAvatar.cpp @@ -2280,8 +2280,18 @@ void MyAvatar::removeHoldAction(AvatarActionHold* holdAction) { } void MyAvatar::updateHoldActions(const AnimPose& prePhysicsPose, const AnimPose& postUpdatePose) { - std::lock_guard guard(_holdActionsMutex); - for (auto& holdAction : _holdActions) { - holdAction->lateAvatarUpdate(prePhysicsPose, postUpdatePose); + EntityTreeRenderer* entityTreeRenderer = qApp->getEntities(); + EntityTreePointer entityTree = entityTreeRenderer ? entityTreeRenderer->getTree() : nullptr; + if (entityTree) { + // to prevent actions from adding or removing themselves from the _holdActions vector + // while we are iterating, we need to enter a critical section. + std::lock_guard guard(_holdActionsMutex); + + // lateAvatarUpdate will modify entity position & orientation, so we need an entity write lock + entityTree->withWriteLock([&] { + for (auto& holdAction : _holdActions) { + holdAction->lateAvatarUpdate(prePhysicsPose, postUpdatePose); + } + }); } }