Add the unref work items to the front of the workqueue (Bug #3273)

Ensures that memory still gets freed even if the workqueue is overloaded.
openmw-39
scrawl 9 years ago
parent bc36269617
commit 2f8be401cc

@ -238,7 +238,7 @@ namespace MWWorld
} }
// the resource cache is cleared from the worker thread so that we're not holding up the main thread with delete operations // the resource cache is cleared from the worker thread so that we're not holding up the main thread with delete operations
mWorkQueue->addWorkItem(new UpdateCacheItem(mResourceSystem, mTerrain, timestamp)); mWorkQueue->addWorkItem(new UpdateCacheItem(mResourceSystem, mTerrain, timestamp), true);
} }
void CellPreloader::setExpiryDelay(double expiryDelay) void CellPreloader::setExpiryDelay(double expiryDelay)

@ -40,7 +40,7 @@ namespace SceneUtil
if (mWorkItem->mObjects.empty()) if (mWorkItem->mObjects.empty())
return; return;
workQueue->addWorkItem(mWorkItem); workQueue->addWorkItem(mWorkItem, true);
mWorkItem = new UnrefWorkItem; mWorkItem = new UnrefWorkItem;
} }

@ -55,7 +55,7 @@ WorkQueue::~WorkQueue()
{ {
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
while (!mQueue.empty()) while (!mQueue.empty())
mQueue.pop(); mQueue.pop_back();
mIsReleased = true; mIsReleased = true;
mCondition.broadcast(); mCondition.broadcast();
} }
@ -67,7 +67,7 @@ WorkQueue::~WorkQueue()
} }
} }
void WorkQueue::addWorkItem(osg::ref_ptr<WorkItem> item) void WorkQueue::addWorkItem(osg::ref_ptr<WorkItem> item, bool front)
{ {
if (item->isDone()) if (item->isDone())
{ {
@ -76,7 +76,10 @@ void WorkQueue::addWorkItem(osg::ref_ptr<WorkItem> item)
} }
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex); OpenThreads::ScopedLock<OpenThreads::Mutex> lock(mMutex);
mQueue.push(item); if (front)
mQueue.push_front(item);
else
mQueue.push_back(item);
mCondition.signal(); mCondition.signal();
} }
@ -90,7 +93,7 @@ osg::ref_ptr<WorkItem> WorkQueue::removeWorkItem()
if (!mQueue.empty()) if (!mQueue.empty())
{ {
osg::ref_ptr<WorkItem> item = mQueue.front(); osg::ref_ptr<WorkItem> item = mQueue.front();
mQueue.pop(); mQueue.pop_front();
return item; return item;
} }
else else

@ -50,7 +50,8 @@ namespace SceneUtil
/// Add a new work item to the back of the queue. /// Add a new work item to the back of the queue.
/// @par The work item's waitTillDone() method may be used by the caller to wait until the work is complete. /// @par The work item's waitTillDone() method may be used by the caller to wait until the work is complete.
void addWorkItem(osg::ref_ptr<WorkItem> item); /// @param front If true, add item to the front of the queue. If false (default), add to the back.
void addWorkItem(osg::ref_ptr<WorkItem> item, bool front=false);
/// Get the next work item from the front of the queue. If the queue is empty, waits until a new item is added. /// Get the next work item from the front of the queue. If the queue is empty, waits until a new item is added.
/// If the workqueue is in the process of being destroyed, may return NULL. /// If the workqueue is in the process of being destroyed, may return NULL.
@ -59,7 +60,7 @@ namespace SceneUtil
private: private:
bool mIsReleased; bool mIsReleased;
std::queue<osg::ref_ptr<WorkItem> > mQueue; std::deque<osg::ref_ptr<WorkItem> > mQueue;
OpenThreads::Mutex mMutex; OpenThreads::Mutex mMutex;
OpenThreads::Condition mCondition; OpenThreads::Condition mCondition;

Loading…
Cancel
Save