Add PreloadItem::abort() to avoid no longer required cells from blocking the work thread

coverity_scan^2
scrawl 8 years ago
parent d62c4259bd
commit a46593fa74

@ -55,6 +55,7 @@ namespace MWWorld
, mKeyframeManager(keyframeManager)
, mTerrain(terrain)
, mPreloadInstances(preloadInstances)
, mAbort(false)
{
ListModelsVisitor visitor (mMeshes);
if (cell->getState() == MWWorld::CellStore::State_Loaded)
@ -76,6 +77,11 @@ namespace MWWorld
}
}
virtual void abort()
{
mAbort = true;
}
/// Preload work to be called from the worker thread.
virtual void doWork()
{
@ -92,6 +98,9 @@ namespace MWWorld
for (MeshList::const_iterator it = mMeshes.begin(); it != mMeshes.end(); ++it)
{
if (mAbort)
break;
try
{
std::string mesh = *it;
@ -144,6 +153,8 @@ namespace MWWorld
Terrain::World* mTerrain;
bool mPreloadInstances;
volatile bool mAbort;
// keep a ref to the loaded objects to make sure it stays loaded as long as this cell is in the preloaded state
std::vector<osg::ref_ptr<const osg::Object> > mPreloadedObjects;
};
@ -187,7 +198,10 @@ namespace MWWorld
CellPreloader::~CellPreloader()
{
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();++it)
{
it->second.mWorkItem->abort();
it->second.mWorkItem->waitTillDone();
}
mPreloadCells.clear();
}
@ -228,7 +242,10 @@ namespace MWWorld
}
if (oldestTimestamp + threshold < timestamp)
{
oldestCell->second.mWorkItem->abort();
mPreloadCells.erase(oldestCell);
}
else
return;
}
@ -246,7 +263,10 @@ namespace MWWorld
{
// do the deletion in the background thread
if (found->second.mWorkItem)
{
found->second.mWorkItem->abort();
mUnrefQueue->push(mPreloadCells[cell].mWorkItem);
}
mPreloadCells.erase(found);
}
@ -257,7 +277,10 @@ namespace MWWorld
for (PreloadMap::iterator it = mPreloadCells.begin(); it != mPreloadCells.end();)
{
if (mPreloadCells.size() >= mMinCacheSize && it->second.mTimeStamp < timestamp - mExpiryDelay)
{
it->second.mWorkItem->abort();
mPreloadCells.erase(it++);
}
else
++it;
}

@ -31,6 +31,9 @@ namespace SceneUtil
/// Internal use by the WorkQueue.
void signalDone();
/// Set abort flag in order to return from doWork() as soon as possible. May not be respected by all WorkItems.
virtual void abort() {}
protected:
OpenThreads::Atomic mDone;
OpenThreads::Mutex mMutex;

Loading…
Cancel
Save