Hi Robert,

sorry, that it was not clear enough. What I tried to explain is in summary that 
the database pager starts twice as many threads as it should but keeps track of 
only half of them. Therefore, when the viewer is closed the database pager only 
cancels half of them while the other half is still running. And the still 
running threads then access via the "_pager" pointer the non-existing database 
pager.

This is what happens in details and what I tried to explain by pasting the 
relevant code previously:
The database pager keeps track of the running threads in "_databaseThreads". 
When setting up "_databaseThreads" (currently empty) in requestNodeFile the 
threads are immediately created and started (in "setUpThreads"). To be precise, 
the threads are actually started in Thread::start() which is called from 
"setUpThreads".
At this moment N threads have been created, started and are tracked in 
"_databaseThreads".
Afterwards, the mentioned for-loop starts again(!) N threads but uses the same 
list (namely "_databaseThreads") to track them. Therefore, from the now running 
2*N threads N are running untracked.

This can also be seen when looking with a debugger at the number of threads the 
database pager has been generated.

This bug can be solved by

a) moving the "_startThreadCalled" assignment further down

Code:
            _done = false;
            OSG_INFO<<"DatabasePager::startThread()"<<std::endl;

            if (_databaseThreads.empty())
            {
                setUpThreads(
                    
osg::DisplaySettings::instance()->getNumOfDatabaseThreadsHint(),
                    
osg::DisplaySettings::instance()->getNumOfHttpDatabaseThreadsHint());
            }

                                        for(DatabaseThreadList::const_iterator 
dt_itr = _databaseThreads.begin();
                dt_itr != _databaseThreads.end();
                ++dt_itr)
            {
                (*dt_itr)->startThread();
            }
            _startThreadCalled = true;




or 

b) inserting an else-statement to start either only newly added or the already 
existing threads


Code:
            _startThreadCalled = true;
            _done = false;
            OSG_INFO<<"DatabasePager::startThread()"<<std::endl;

            if (_databaseThreads.empty())
            {
                setUpThreads(
                    
osg::DisplaySettings::instance()->getNumOfDatabaseThreadsHint(),
                    
osg::DisplaySettings::instance()->getNumOfHttpDatabaseThreadsHint());
            }
                                        else
                                        for(DatabaseThreadList::const_iterator 
dt_itr = _databaseThreads.begin();
                dt_itr != _databaseThreads.end();
                ++dt_itr)
            {
                (*dt_itr)->startThread();
            }




Which solution is chosen is a matter of taste.

I also recommend to document the functionality of "_startThreadCalled" because 
the wrong usage (or better hidden effects) of this flag in the above mentioned 
code causes the bug.

I can provide a patch but I first would like to make sure that my analysis are 
correct (I think so but I am not an expert).

Cheers,
Hartwig

------------------
Read this topic online here:
http://forum.openscenegraph.org/viewtopic.php?p=73164#73164





_______________________________________________
osg-users mailing list
[email protected]
http://lists.openscenegraph.org/listinfo.cgi/osg-users-openscenegraph.org

Reply via email to