From 3d43f73a882ddcad9a79424a8f0b35d016db90bf Mon Sep 17 00:00:00 2001 From: "Anthony J. Thibault" Date: Thu, 31 Mar 2016 17:57:20 -0700 Subject: [PATCH] Application: don't call Model::simulate on network thread. This can cause a crash. On startup the Application::processOctreeStats method on the network thread will call into entities entity->isReadyToComputeShape() (without a tree lock) and trigger Model::simulate. Model is NOT thread safe. This was leading to a single model to be initialized on two threads simultaneously. This might be somewhat rare, I only caught it because I was running a debug build. --- interface/src/Application.cpp | 36 +++++++++++++++++++---------------- interface/src/Application.h | 2 ++ 2 files changed, 22 insertions(+), 16 deletions(-) diff --git a/interface/src/Application.cpp b/interface/src/Application.cpp index ffc9b0333c..bd1a44fc76 100644 --- a/interface/src/Application.cpp +++ b/interface/src/Application.cpp @@ -3215,6 +3215,25 @@ void Application::update(float deltaTime) { updateLOD(); + if (!_physicsEnabled && _processOctreeStatsCounter > 0) { + + // process octree stats packets are sent in between full sends of a scene. + // We keep physics disabled until we've recieved a full scene and everything near the avatar in that + // scene is ready to compute its collision shape. + + if (nearbyEntitiesAreReadyForPhysics()) { + _physicsEnabled = true; + getMyAvatar()->updateMotionBehaviorFromMenu(); + } else { + auto characterController = getMyAvatar()->getCharacterController(); + if (characterController) { + // if we have a character controller, disable it here so the avatar doesn't get stuck due to + // a non-loading collision hull. + characterController->setEnabled(false); + } + } + } + { PerformanceTimer perfTimer("devices"); DeviceTracker::updateAll(); @@ -4260,22 +4279,7 @@ int Application::processOctreeStats(ReceivedMessage& message, SharedNodePointer }); }); - if (!_physicsEnabled) { - if (nearbyEntitiesAreReadyForPhysics()) { - // These stats packets are sent in between full sends of a scene. - // We keep physics disabled until we've recieved a full scene and everything near the avatar in that - // scene is ready to compute its collision shape. - _physicsEnabled = true; - getMyAvatar()->updateMotionBehaviorFromMenu(); - } else { - auto characterController = getMyAvatar()->getCharacterController(); - if (characterController) { - // if we have a character controller, disable it here so the avatar doesn't get stuck due to - // a non-loading collision hull. - characterController->setEnabled(false); - } - } - } + _processOctreeStatsCounter++; return statsMessageLength; } diff --git a/interface/src/Application.h b/interface/src/Application.h index 31c865ad90..2512bc7918 100644 --- a/interface/src/Application.h +++ b/interface/src/Application.h @@ -515,6 +515,8 @@ private: std::map> _preRenderLambdas; std::mutex _preRenderLambdasLock; + + std::atomic _processOctreeStatsCounter { 0 }; }; #endif // hifi_Application_h