diff --git a/include/osgDB/DatabasePager b/include/osgDB/DatabasePager index 099de9f0a..72d51c31d 100644 --- a/include/osgDB/DatabasePager +++ b/include/osgDB/DatabasePager @@ -407,28 +407,29 @@ class OSGDB_EXPORT DatabasePager : public osg::NodeVisitor::DatabaseRequestHandl struct ReadQueue : public RequestQueue { ReadQueue(DatabasePager* pager, const std::string& name); - + void block() { _block->block(); } - + void release() { _block->release(); } - + void updateBlock() { - _block->set((!_requestList.empty() || !_childrenToDeleteList.empty()) && - !_pager->_databasePagerThreadPaused); + _block->set((!_requestList.empty() || !_childrenToDeleteList.empty()) && + !_pager->_databasePagerThreadPaused); } - + void clear(); - + void add(DatabaseRequest* databaseRequest); - + void takeFirst(osg::ref_ptr& databaseRequest); - + osg::ref_ptr _block; - + DatabasePager* _pager; std::string _name; - + int _frameNumberLastPruned; + OpenThreads::Mutex _childrenToDeleteListMutex; ObjectList _childrenToDeleteList; }; diff --git a/src/osgDB/DatabasePager.cpp b/src/osgDB/DatabasePager.cpp index 3be65e9aa..9b31bddef 100644 --- a/src/osgDB/DatabasePager.cpp +++ b/src/osgDB/DatabasePager.cpp @@ -289,7 +289,6 @@ void DatabasePager::DatabaseRequest::invalidate() _loadedModel = 0; _dataToCompileMap.clear(); _requestQueue = 0; - _requestQueue = 0; } DatabasePager::RequestQueue::~RequestQueue() @@ -315,7 +314,8 @@ void DatabasePager::RequestQueue::sort() // DatabasePager::ReadQueue::ReadQueue(DatabasePager* pager, const std::string& name): _pager(pager), - _name(name) + _name(name), + _frameNumberLastPruned(-1) { _block = new osg::RefBlock; } @@ -328,8 +328,7 @@ void DatabasePager::ReadQueue::clear() citr != _requestList.end(); ++citr) { - (*citr)->_loadedModel = 0; - (*citr)->_requestQueue = 0; + (*citr)->invalidate(); } _requestList.clear(); @@ -353,10 +352,35 @@ void DatabasePager::ReadQueue::takeFirst(osg::ref_ptr& database if (!_requestList.empty()) { sort(); - - databaseRequest = _requestList.front(); - databaseRequest->_requestQueue = 0; - _requestList.erase(_requestList.begin()); + + if (_frameNumberLastPruned != _pager->_frameNumber) + { + // Prune all the old entries. + RequestQueue::RequestList::iterator tooOld + = std::find_if(_requestList.begin(), + _requestList.end(), + refPtrAdapt(std::not1(std::bind2nd(std::mem_fun(&DatabaseRequest::isRequestCurrent), + _pager->_frameNumber)))); + + // delete the entries + for(RequestQueue::RequestList::iterator citr = tooOld; + citr != _requestList.end(); + ++citr) + { + (*citr)->invalidate(); + } + + _requestList.erase(tooOld, _requestList.end()); + + _frameNumberLastPruned = _pager->_frameNumber; + } + + if (!_requestList.empty()) + { + databaseRequest = _requestList.front(); + databaseRequest->_requestQueue = 0; + _requestList.erase(_requestList.begin()); + } updateBlock(); }