Improved the robustness of thread start and cancellation

This commit is contained in:
Robert Osfield 2007-01-03 16:06:12 +00:00
parent 740363133f
commit 4f87afdbf5
7 changed files with 87 additions and 25 deletions

View File

@ -172,7 +172,7 @@ int main( int argc, char **argv )
else viewer.setCameraManipulator( new osgGA::TrackballManipulator() );
viewer.getCamera()->setClearColor(osg::Vec4f(0.6f,0.6f,0.8f,1.0f));
#if 1
#if 0
// singleWindowMultipleCameras(viewer);
@ -187,7 +187,7 @@ int main( int argc, char **argv )
viewer.realize();
bool limitNumberOfFrames = false;
bool limitNumberOfFrames = true;
unsigned int numFrames = 0;
unsigned int maxFrames = 10;

View File

@ -106,6 +106,8 @@ class GraphicsWindowX11 : public osgViewer::GraphicsWindow
protected:
~GraphicsWindowX11();
bool createVisualInfo();
void init();

View File

@ -141,10 +141,6 @@ bool GraphicsContext::realize()
{
if (realizeImplementation())
{
if (_graphicsThread.valid() && !_graphicsThread->isRunning())
{
_graphicsThread->startThread();
}
return true;
}
else
@ -255,12 +251,6 @@ void GraphicsContext::setGraphicsThread(GraphicsThread* gt)
if (_graphicsThread.valid())
{
_graphicsThread->_graphicsContext = this;
#if 0
if (!_graphicsThread->isRunning())
{
_graphicsThread->startThread();
}
#endif
}
}

View File

@ -86,9 +86,11 @@ GraphicsThread::GraphicsThread():
GraphicsThread::~GraphicsThread()
{
osg::notify(osg::INFO)<<"Destructing graphics thread"<<std::endl;
//osg::notify(osg::NOTICE)<<"Destructing graphics thread "<<this<<std::endl;
cancel();
//osg::notify(osg::NOTICE)<<"Done Destructing graphics thread "<<this<<std::endl;
}
void GraphicsThread::setDone(bool done)
@ -117,7 +119,7 @@ void GraphicsThread::setDone(bool done)
int GraphicsThread::cancel()
{
osg::notify(osg::INFO)<<"Cancelling graphics thread "<<this<<std::endl;
osg::notify(osg::INFO)<<"Cancelling graphics thread "<<this<<" isRunning()="<<isRunning()<<std::endl;
int result = 0;
if( isRunning() )
@ -162,6 +164,8 @@ int GraphicsThread::cancel()
}
}
osg::notify(osg::INFO)<<" GraphicsThread::cancel() thread cancelled "<<this<<" isRunning()="<<isRunning()<<std::endl;
return result;
}
@ -279,7 +283,7 @@ void GraphicsThread::run()
// create a local object to clean up once the thread is cancelled.
ThreadExitTidyUp threadExitTypeUp(_graphicsContext, contextRealizedInThisThread);
osg::notify(osg::INFO)<<"Doing run"<<std::endl;
osg::notify(osg::INFO)<<"Doing run "<<this<<" isRunning()="<<isRunning()<<std::endl;
bool firstTime = true;
@ -366,7 +370,7 @@ void GraphicsThread::run()
} while (!testCancel() && !_done);
osg::notify(osg::INFO)<<"exit loop "<<this<<std::endl;
osg::notify(osg::INFO)<<"exit loop "<<this<<" isRunning()="<<isRunning()<<std::endl;
}

View File

@ -129,7 +129,7 @@ int DatabasePager::cancel()
_done = true;
// cancel the thread..
result = Thread::cancel();
// result = Thread::cancel();
//join();
// release the frameBlock and _databasePagerThreadBlock incase its holding up thread cancelation.

View File

@ -223,6 +223,11 @@ static int remapX11Key(int key)
return s_x11KeyboardMap.remapKey(key);
}
GraphicsWindowX11::~GraphicsWindowX11()
{
close(true);
}
bool GraphicsWindowX11::createVisualInfo()
{
typedef std::vector<int> Attributes;
@ -527,19 +532,48 @@ bool GraphicsWindowX11::realizeImplementation()
void GraphicsWindowX11::makeCurrentImplementation()
{
if (!_realized) return;
if (!_realized)
{
osg::notify(osg::NOTICE)<<"Warning: GraphicsWindow not realized, cannot do makeCurrent."<<std::endl;
return;
}
// osg::notify(osg::NOTICE)<<"makeCurrentImplementation "<<this<<" "<<OpenThreads::Thread::CurrentThread()<<std::endl;
// osg::notify(osg::NOTICE)<<" glXMakeCurrent ("<<_display<<","<<_window<<","<<_glxContext<<std::endl;
// checkEvents();
glXMakeCurrent( _display, _window, _glxContext );
// XFlush(_display);
// XSync(_display,0);
if (glXMakeCurrent( _display, _window, _glxContext ))
{
// osg::notify(osg::NOTICE)<<"makeCurrentImplementation sucessful"<<std::endl;
}
else
{
osg::notify(osg::NOTICE)<<"makeCurrentImplementation failed"<<std::endl;
while(!glXMakeCurrent( _display, _window, _glxContext ))
{
OpenThreads::Thread::YieldCurrentThread();
osg::notify(osg::NOTICE)<<" makeCurrentImplementation failed again."<<std::endl;
}
// osg::notify(osg::NOTICE)<<" Succeeded at last."<<std::endl;
}
}
void GraphicsWindowX11::closeImplementation()
{
// osg::notify(osg::NOTICE)<<"Closing GraphicsWindowX11"<<std::endl;
if (_display && _window)
{
//glXDestroyContext(_display, _glxContext );
@ -889,11 +923,19 @@ void GraphicsWindowX11::requestWarpPointer(float x,float y)
getEventQueue()->mouseWarped(x,y);
}
int X11ErrorHandling(Display* display, XErrorEvent* event)
{
osg::notify(osg::NOTICE)<<"Got an X11ErrorHandling call"<<std::endl;
}
struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSystemInterface
{
X11WindowingSystemInterface()
{
XSetErrorHandler(X11ErrorHandling);
#if 1
if (XInitThreads() == 0)
{
@ -907,6 +949,11 @@ struct X11WindowingSystemInterface : public osg::GraphicsContext::WindowingSyste
#endif
}
~X11WindowingSystemInterface()
{
XSetErrorHandler(0);
}
virtual unsigned int getNumScreens(const osg::GraphicsContext::ScreenIdentifier& si)
{
Display* display = XOpenDisplay(si.displayName().c_str());

View File

@ -31,7 +31,8 @@ Viewer::Viewer():
Viewer::~Viewer()
{
#if 0
//osg::notify(osg::NOTICE)<<"Viewer::~Viewer()"<<std::endl;
Contexts contexts;
getContexts(contexts);
@ -49,7 +50,8 @@ Viewer::~Viewer()
_scene->getDatabasePager()->cancel();
_scene->setDatabasePager(0);
}
#endif
//osg::notify(osg::NOTICE)<<"finish Viewer::~Viewer()"<<std::endl;
}
void Viewer::setThreadingModel(ThreadingModel threadingModel)
@ -184,7 +186,7 @@ struct RunOperations : public osg::GraphicsOperation
void Viewer::realize()
{
osg::notify(osg::INFO)<<"Viewer::realize()"<<std::endl;
//osg::notify(osg::INFO)<<"Viewer::realize()"<<std::endl;
setCameraWithFocus(0);
@ -193,31 +195,43 @@ void Viewer::realize()
Contexts contexts;
getContexts(contexts);
int numProcessors = OpenThreads::GetNumberOfProcessors();
bool multiThreaded = contexts.size() > 1 && _threadingModel>=ThreadPerContext;
bool affinity = true;
if (multiThreaded)
{
bool firstContextAsMainThread = _threadingModel==ThreadPerContext;
unsigned int numThreadsIncludingMainThread = firstContextAsMainThread ? contexts.size() : contexts.size()+1;
osg::notify(osg::NOTICE)<<"numThreadsIncludingMainThread=="<<numThreadsIncludingMainThread<<std::endl;
// osg::notify(osg::NOTICE)<<"numThreadsIncludingMainThread=="<<numThreadsIncludingMainThread<<std::endl;
_startRenderingBarrier = new osg::BarrierOperation(numThreadsIncludingMainThread, osg::BarrierOperation::NO_OPERATION);
_endRenderingDispatchBarrier = new osg::BarrierOperation(numThreadsIncludingMainThread, osg::BarrierOperation::NO_OPERATION);
osg::ref_ptr<osg::SwapBuffersOperation> swapOp = new osg::SwapBuffersOperation();
citr = contexts.begin();
if (firstContextAsMainThread) ++citr;
unsigned int processNum = 0;
if (firstContextAsMainThread)
{
if (affinity) OpenThreads::SetProcessorAffinityOfCurrentThread(processNum % numProcessors);
++processNum;
++citr;
}
for(;
citr != contexts.end();
++citr)
++citr,
++processNum)
{
osg::GraphicsContext* gc = (*citr);
// create the a graphics thread for this context
gc->createGraphicsThread();
if (affinity) gc->getGraphicsThread()->setProcessorAffinity(processNum % numProcessors);
gc->getGraphicsThread()->add(new CompileOperation(getSceneData()));
// add the startRenderingBarrier
@ -264,6 +278,8 @@ void Viewer::realize()
if (multiThreaded)
{
//osg::notify(osg::NOTICE)<<"Ready to start threads"<<std::endl;
for(citr = contexts.begin();
citr != contexts.end();
++citr)
@ -271,10 +287,13 @@ void Viewer::realize()
osg::GraphicsContext* gc = (*citr);
if (gc->getGraphicsThread() && !gc->getGraphicsThread()->isRunning())
{
//osg::notify(osg::NOTICE)<<" gc->getGraphicsThread()->startThread() "<<gc->getGraphicsThread()<<std::endl;
gc->getGraphicsThread()->startThread();
OpenThreads::Thread::YieldCurrentThread();
}
}
//osg::notify(osg::NOTICE)<<"Started threads"<<std::endl;
}
}