diff --git a/assignment-client/src/entities/EntityServer.cpp b/assignment-client/src/entities/EntityServer.cpp index a6ab382781..e56adfd16a 100644 --- a/assignment-client/src/entities/EntityServer.cpp +++ b/assignment-client/src/entities/EntityServer.cpp @@ -376,9 +376,7 @@ void EntityServer::nodeAdded(SharedNodePointer node) { void EntityServer::nodeKilled(SharedNodePointer node) { EntityTreePointer tree = std::static_pointer_cast(_tree); - tree->withWriteLock([&] { - tree->deleteDescendantsOfAvatar(node->getUUID()); - }); + tree->deleteDescendantsOfAvatar(node->getUUID()); tree->forgetAvatarID(node->getUUID()); OctreeServer::nodeKilled(node); } diff --git a/libraries/entities/src/EntityTree.cpp b/libraries/entities/src/EntityTree.cpp index fedda7a42e..a22f34a874 100644 --- a/libraries/entities/src/EntityTree.cpp +++ b/libraries/entities/src/EntityTree.cpp @@ -2213,6 +2213,7 @@ void EntityTree::fixupNeedsParentFixups() { entity->postParentFixup(); } else if (getIsServer() || _avatarIDs.contains(entity->getParentID())) { + std::lock_guard lock(_childrenOfAvatarsLock); // this is a child of an avatar, which the entity server will never have // a SpatiallyNestable object for. Add it to a list for cleanup when the avatar leaves. if (!_childrenOfAvatars.contains(entity->getParentID())) { @@ -2241,6 +2242,7 @@ void EntityTree::fixupNeedsParentFixups() { } void EntityTree::deleteDescendantsOfAvatar(QUuid avatarID) { + std::lock_guard lock(_childrenOfAvatarsLock); QHash>::const_iterator itr = _childrenOfAvatars.constFind(avatarID); if (itr != _childrenOfAvatars.end()) { if (!itr.value().empty()) { @@ -2259,8 +2261,10 @@ void EntityTree::deleteDescendantsOfAvatar(QUuid avatarID) { void EntityTree::removeFromChildrenOfAvatars(EntityItemPointer entity) { QUuid avatarID = entity->getParentID(); - if (_childrenOfAvatars.contains(avatarID)) { - _childrenOfAvatars[avatarID].remove(entity->getID()); + std::lock_guard lock(_childrenOfAvatarsLock); + auto itr = _childrenOfAvatars.find(avatarID); + if (itr != _childrenOfAvatars.end()) { + itr.value().remove(entity->getID()); } } diff --git a/libraries/entities/src/EntityTree.h b/libraries/entities/src/EntityTree.h index 2d5119d626..85f2310edb 100644 --- a/libraries/entities/src/EntityTree.h +++ b/libraries/entities/src/EntityTree.h @@ -366,6 +366,7 @@ protected: // we maintain a list of avatarIDs to notice when an entity is a child of one. QSet _avatarIDs; // IDs of avatars connected to entity server + std::mutex _childrenOfAvatarsLock; QHash> _childrenOfAvatars; // which entities are children of which avatars float _maxTmpEntityLifetime { DEFAULT_MAX_TMP_ENTITY_LIFETIME };