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