From 3f3d00ffc92644acd0f7d99db5bdb9e5e01f2581 Mon Sep 17 00:00:00 2001 From: scrawl Date: Thu, 9 Feb 2017 04:03:38 +0100 Subject: [PATCH] Add CellPreloader::clear to avoid potential dangling CellStore pointer and to more aggressively clear preload state from a previous game --- apps/openmw/mwworld/cellpreloader.cpp | 20 +++++++++++++++++++- apps/openmw/mwworld/cellpreloader.hpp | 2 ++ apps/openmw/mwworld/scene.cpp | 4 +++- apps/openmw/mwworld/scene.hpp | 2 +- apps/openmw/mwworld/worldimp.cpp | 2 +- 5 files changed, 26 insertions(+), 4 deletions(-) diff --git a/apps/openmw/mwworld/cellpreloader.cpp b/apps/openmw/mwworld/cellpreloader.cpp index 3608699fb..7b90da43b 100644 --- a/apps/openmw/mwworld/cellpreloader.cpp +++ b/apps/openmw/mwworld/cellpreloader.cpp @@ -272,13 +272,31 @@ namespace MWWorld } } + void CellPreloader::clear() + { + for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();) + { + if (it->second.mWorkItem) + { + it->second.mWorkItem->abort(); + mUnrefQueue->push(it->second.mWorkItem); + } + + mPreloadCells.erase(it++); + } + } + void CellPreloader::updateCache(double timestamp) { for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();) { if (mPreloadCells.size() >= mMinCacheSize && it->second.mTimeStamp < timestamp - mExpiryDelay) { - it->second.mWorkItem->abort(); + if (it->second.mWorkItem) + { + it->second.mWorkItem->abort(); + mUnrefQueue->push(it->second.mWorkItem); + } mPreloadCells.erase(it++); } else diff --git a/apps/openmw/mwworld/cellpreloader.hpp b/apps/openmw/mwworld/cellpreloader.hpp index 3836b6869..e8e59a3a2 100644 --- a/apps/openmw/mwworld/cellpreloader.hpp +++ b/apps/openmw/mwworld/cellpreloader.hpp @@ -37,6 +37,8 @@ namespace MWWorld void notifyLoaded(MWWorld::CellStore* cell); + void clear(); + /// Removes preloaded cells that have not had a preload request for a while. void updateCache(double timestamp); diff --git a/apps/openmw/mwworld/scene.cpp b/apps/openmw/mwworld/scene.cpp index 30d021bfd..3917518a2 100644 --- a/apps/openmw/mwworld/scene.cpp +++ b/apps/openmw/mwworld/scene.cpp @@ -315,13 +315,15 @@ namespace MWWorld mPreloader->notifyLoaded(cell); } - void Scene::changeToVoid() + void Scene::clear() { CellStoreCollection::iterator active = mActiveCells.begin(); while (active!=mActiveCells.end()) unloadCell (active++); assert(mActiveCells.empty()); mCurrentCell = NULL; + + mPreloader->clear(); } void Scene::playerMoved(const osg::Vec3f &pos) diff --git a/apps/openmw/mwworld/scene.hpp b/apps/openmw/mwworld/scene.hpp index b8cbf49b9..328538076 100644 --- a/apps/openmw/mwworld/scene.hpp +++ b/apps/openmw/mwworld/scene.hpp @@ -113,7 +113,7 @@ namespace MWWorld ///< Move to exterior cell. /// @param changeEvent Set cellChanged flag? - void changeToVoid(); + void clear(); ///< Change into a void void markCellAsUnchanged(); diff --git a/apps/openmw/mwworld/worldimp.cpp b/apps/openmw/mwworld/worldimp.cpp index 06e9856e2..0229f1f93 100644 --- a/apps/openmw/mwworld/worldimp.cpp +++ b/apps/openmw/mwworld/worldimp.cpp @@ -290,7 +290,7 @@ namespace MWWorld mProjectileManager->clear(); mLocalScripts.clear(); - mWorldScene->changeToVoid(); + mWorldScene->clear(); mStore.clearDynamic(); mStore.setUp();