Added better control for cancel GraphicsThreads.
This commit is contained in:
parent
b19c005178
commit
c2f1527fe0
@ -90,6 +90,22 @@ struct DrawOperation : public osg::GraphicsThread::Operation
|
||||
osg::ref_ptr<osgUtil::SceneView> _sceneView;
|
||||
};
|
||||
|
||||
struct CleanUpOperation : public osg::GraphicsThread::Operation
|
||||
{
|
||||
CleanUpOperation(osgUtil::SceneView* sceneView):
|
||||
osg::GraphicsThread::Operation("CleanUp",false),
|
||||
_sceneView(sceneView)
|
||||
{
|
||||
}
|
||||
|
||||
virtual void operator () (osg::GraphicsContext*)
|
||||
{
|
||||
_sceneView->releaseAllGLObjects();
|
||||
_sceneView->flushAllDeletedGLObjects();
|
||||
}
|
||||
|
||||
osg::ref_ptr<osgUtil::SceneView> _sceneView;
|
||||
};
|
||||
|
||||
// main does the following steps to create a multi-thread, multiple camera/graphics context view of a scene graph.
|
||||
//
|
||||
@ -347,7 +363,24 @@ int main( int argc, char **argv )
|
||||
|
||||
}
|
||||
|
||||
|
||||
std::cout<<"Exiting application"<<std::endl;
|
||||
|
||||
// start clean up.
|
||||
for(gitr = graphicsContextSet.begin();
|
||||
gitr != graphicsContextSet.end();
|
||||
++gitr)
|
||||
{
|
||||
osg::GraphicsContext* context = *gitr;
|
||||
osg::GraphicsThread* thread = context->getGraphicsThread();
|
||||
if (thread)
|
||||
{
|
||||
thread->removeAllOperations();
|
||||
thread->setDone(true);
|
||||
}
|
||||
}
|
||||
|
||||
std::cout<<"Removed all operations"<<std::endl;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -100,6 +100,9 @@ class OSG_EXPORT GraphicsThread : public Referenced, public OpenThreads::Thread
|
||||
/** Get whether the operation should be kept once its been applied.*/
|
||||
bool getKeep() const { return _keep; }
|
||||
|
||||
/** if this operation is a barrier then release it.*/
|
||||
virtual void release() {}
|
||||
|
||||
/** Do the actual task of this operation.*/
|
||||
virtual void operator () (GraphicsContext*) {}
|
||||
|
||||
@ -111,9 +114,24 @@ class OSG_EXPORT GraphicsThread : public Referenced, public OpenThreads::Thread
|
||||
* executed by the graphics thread once this operation gets to the head of the queue.*/
|
||||
void add(Operation* operation, bool waitForCompletion=false);
|
||||
|
||||
/** Remove operation from OperationQueue.*/
|
||||
void remove(Operation* operation);
|
||||
|
||||
/** Remove named operation from OperationQueue.*/
|
||||
void remove(const std::string& name);
|
||||
|
||||
/** Remove all operations from OperationQueue.*/
|
||||
void removeAllOperations();
|
||||
|
||||
/** Get the operation currently being run.*/
|
||||
osg::ref_ptr<Operation> getCurrentOperation() { return _currentOperation; }
|
||||
|
||||
/** Run does the graphics thread run loop.*/
|
||||
virtual void run();
|
||||
|
||||
void setDone(bool done);
|
||||
bool getDone() const { return _done; }
|
||||
|
||||
/** Cancel this graphics thread.*/
|
||||
virtual int cancel();
|
||||
|
||||
@ -131,6 +149,7 @@ class OSG_EXPORT GraphicsThread : public Referenced, public OpenThreads::Thread
|
||||
OpenThreads::Mutex _operationsMutex;
|
||||
osg::ref_ptr<osg::Block> _operationsBlock;
|
||||
OperationQueue _operations;
|
||||
osg::ref_ptr<Operation> _currentOperation;
|
||||
|
||||
};
|
||||
|
||||
@ -159,6 +178,8 @@ struct OSG_EXPORT BarrierOperation : public GraphicsThread::Operation, public Op
|
||||
OpenThreads::Barrier(numThreads),
|
||||
_preBlockOp(op) {}
|
||||
|
||||
virtual void release();
|
||||
|
||||
virtual void operator () (GraphicsContext* context);
|
||||
|
||||
PreBlockOp _preBlockOp;
|
||||
@ -171,6 +192,8 @@ struct OSG_EXPORT ReleaseContext_Block_MakeCurrentOperation : public GraphicsThr
|
||||
ReleaseContext_Block_MakeCurrentOperation():
|
||||
GraphicsThread::Operation("ReleaseContext_Block_MakeCurrent", false) {}
|
||||
|
||||
virtual void release();
|
||||
|
||||
virtual void operator () (GraphicsContext* context);
|
||||
};
|
||||
|
||||
|
@ -25,25 +25,25 @@ struct ThreadExitTidyUp
|
||||
_context(context),
|
||||
_closeContextOnExit(closeContextOnExit)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"starting thread context "<<_context<<std::endl;
|
||||
osg::notify(osg::INFO)<<"starting thread context "<<_context<<std::endl;
|
||||
}
|
||||
|
||||
~ThreadExitTidyUp()
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<"exit thread"<<std::endl;
|
||||
osg::notify(osg::INFO)<<"exit thread"<<std::endl;
|
||||
if (_context)
|
||||
{
|
||||
if (_closeContextOnExit)
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" - close context "<<_context<<std::endl;
|
||||
osg::notify(osg::INFO)<<" - close context "<<_context<<std::endl;
|
||||
|
||||
_context->closeImplementation();
|
||||
|
||||
osg::notify(osg::NOTICE)<<" - done close context "<<_context<<std::endl;
|
||||
osg::notify(osg::INFO)<<" - done close context "<<_context<<std::endl;
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::NOTICE)<<" - releaseContext "<<_context<<std::endl;
|
||||
osg::notify(osg::INFO)<<" - releaseContext "<<_context<<std::endl;
|
||||
|
||||
//_context->releaseContext();
|
||||
}
|
||||
@ -64,10 +64,15 @@ struct BlockOperation : public GraphicsThread::Operation, public Block
|
||||
reset();
|
||||
}
|
||||
|
||||
virtual void release()
|
||||
{
|
||||
Block::release();
|
||||
}
|
||||
|
||||
virtual void operator () (GraphicsContext*)
|
||||
{
|
||||
glFlush();
|
||||
release();
|
||||
Block::release();
|
||||
}
|
||||
};
|
||||
|
||||
@ -86,6 +91,30 @@ GraphicsThread::~GraphicsThread()
|
||||
cancel();
|
||||
}
|
||||
|
||||
void GraphicsThread::setDone(bool done)
|
||||
{
|
||||
if (_done==done) return;
|
||||
|
||||
_done = true;
|
||||
|
||||
if (done)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"set done "<<this<<std::endl;
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
if (_currentOperation.valid())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"releasing "<<_currentOperation.get()<<std::endl;
|
||||
_currentOperation->release();
|
||||
}
|
||||
}
|
||||
|
||||
_operationsBlock->release();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int GraphicsThread::cancel()
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Cancelling graphics thread "<<this<<std::endl;
|
||||
@ -102,37 +131,28 @@ int GraphicsThread::cancel()
|
||||
itr != _operations.end();
|
||||
++itr)
|
||||
{
|
||||
BarrierOperation* barrier = dynamic_cast<BarrierOperation*>(itr->get());
|
||||
if (barrier)
|
||||
{
|
||||
barrier->release();
|
||||
//barrier->invalidate();
|
||||
osg::notify(osg::INFO)<<" Invalidating barrier "<<this<<std::endl;
|
||||
}
|
||||
(*itr)->release();
|
||||
}
|
||||
|
||||
/*
|
||||
// cancel the thread..
|
||||
result = Thread::cancel();
|
||||
//join();
|
||||
*/
|
||||
// release the frameBlock and _databasePagerThreadBlock incase its holding up thread cancelation.
|
||||
_operationsBlock->release();
|
||||
|
||||
// then wait for the the thread to stop running.
|
||||
while(isRunning())
|
||||
{
|
||||
for(OperationQueue::iterator itr = _operations.begin();
|
||||
itr != _operations.end();
|
||||
++itr)
|
||||
_operationsBlock->release();
|
||||
|
||||
{
|
||||
BarrierOperation* barrier = dynamic_cast<BarrierOperation*>(itr->get());
|
||||
if (barrier)
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
|
||||
for(OperationQueue::iterator itr = _operations.begin();
|
||||
itr != _operations.end();
|
||||
++itr)
|
||||
{
|
||||
barrier->release();
|
||||
//barrier->invalidate();
|
||||
osg::notify(osg::INFO)<<" Invalidating barrier "<<this<<std::endl;
|
||||
(*itr)->release();
|
||||
}
|
||||
|
||||
if (_currentOperation.valid()) _currentOperation->release();
|
||||
}
|
||||
|
||||
// commenting out debug info as it was cashing crash on exit, presumable
|
||||
@ -174,6 +194,46 @@ void GraphicsThread::add(Operation* operation, bool waitForCompletion)
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsThread::remove(Operation* operation)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Doing remove operation"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
|
||||
for(OperationQueue::iterator itr = _operations.begin();
|
||||
itr!=_operations.end();)
|
||||
{
|
||||
if ((*itr)==operation) itr = _operations.erase(itr);
|
||||
else ++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsThread::remove(const std::string& name)
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Doing remove named operation"<<std::endl;
|
||||
|
||||
// aquire the lock on the operations queue to prevent anyone else for modifying it at the same time
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
|
||||
// find the remove all operations with specificed name
|
||||
for(OperationQueue::iterator itr = _operations.begin();
|
||||
itr!=_operations.end();)
|
||||
{
|
||||
if ((*itr)->getName()==name) itr = _operations.erase(itr);
|
||||
else ++itr;
|
||||
}
|
||||
}
|
||||
|
||||
void GraphicsThread::removeAllOperations()
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Doing remove all operations"<<std::endl;
|
||||
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
_operations.clear();
|
||||
}
|
||||
|
||||
|
||||
void GraphicsThread::run()
|
||||
{
|
||||
bool contextRealizedInThisThread = false;
|
||||
@ -202,12 +262,15 @@ void GraphicsThread::run()
|
||||
|
||||
do
|
||||
{
|
||||
osg::notify(osg::INFO)<<"In main loop"<<std::endl;
|
||||
osg::notify(osg::INFO)<<"In main loop "<<this<<std::endl;
|
||||
|
||||
if (_operations.empty())
|
||||
{
|
||||
_operationsBlock->block();
|
||||
|
||||
// exit from loop if _done is set.
|
||||
if (_done) break;
|
||||
|
||||
itr = _operations.begin();
|
||||
}
|
||||
else
|
||||
@ -215,9 +278,7 @@ void GraphicsThread::run()
|
||||
if (itr == _operations.end()) itr = _operations.begin();
|
||||
}
|
||||
|
||||
osg::notify(osg::INFO)<<"get op"<<std::endl;
|
||||
|
||||
ref_ptr<Operation> operation;
|
||||
osg::notify(osg::INFO)<<"get op "<<_done<<" "<<this<<std::endl;
|
||||
|
||||
// get the front of the file request list.
|
||||
{
|
||||
@ -225,11 +286,11 @@ void GraphicsThread::run()
|
||||
if (!_operations.empty())
|
||||
{
|
||||
// get the next item
|
||||
operation = *itr;
|
||||
_currentOperation = *itr;
|
||||
|
||||
if (!operation->getKeep())
|
||||
if (!_currentOperation->getKeep())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"removing "<<operation->getName()<<std::endl;
|
||||
osg::notify(osg::INFO)<<"removing "<<_currentOperation->getName()<<std::endl;
|
||||
|
||||
// remove it from the opeations queue
|
||||
itr = _operations.erase(itr);
|
||||
@ -244,7 +305,7 @@ void GraphicsThread::run()
|
||||
}
|
||||
else
|
||||
{
|
||||
osg::notify(osg::INFO)<<"increment "<<operation->getName()<<std::endl;
|
||||
osg::notify(osg::INFO)<<"increment "<<_currentOperation->getName()<<std::endl;
|
||||
|
||||
// move on to the next operation in the list.
|
||||
++itr;
|
||||
@ -255,12 +316,17 @@ void GraphicsThread::run()
|
||||
|
||||
}
|
||||
|
||||
if (operation.valid())
|
||||
if (_currentOperation.valid())
|
||||
{
|
||||
osg::notify(osg::INFO)<<"Doing op "<<operation->getName()<<" "<<this<<std::endl;
|
||||
osg::notify(osg::INFO)<<"Doing op "<<_currentOperation->getName()<<" "<<this<<std::endl;
|
||||
|
||||
// call the graphics operation.
|
||||
(*operation)(_graphicsContext);
|
||||
(*_currentOperation)(_graphicsContext);
|
||||
|
||||
{
|
||||
OpenThreads::ScopedLock<OpenThreads::Mutex> lock(_operationsMutex);
|
||||
_currentOperation = 0;
|
||||
}
|
||||
}
|
||||
|
||||
if (firstTime)
|
||||
@ -273,7 +339,7 @@ void GraphicsThread::run()
|
||||
|
||||
} while (!testCancel() && !_done);
|
||||
|
||||
osg::notify(osg::NOTICE)<<"exit loop"<<std::endl;
|
||||
osg::notify(osg::INFO)<<"exit loop "<<this<<std::endl;
|
||||
|
||||
}
|
||||
|
||||
@ -285,6 +351,11 @@ void SwapBuffersOperation::operator () (GraphicsContext* context)
|
||||
}
|
||||
}
|
||||
|
||||
void BarrierOperation::release()
|
||||
{
|
||||
Barrier::release();
|
||||
}
|
||||
|
||||
void BarrierOperation::operator () (GraphicsContext*)
|
||||
{
|
||||
if (_preBlockOp==GL_FLUSH) glFlush();
|
||||
@ -293,6 +364,12 @@ void BarrierOperation::operator () (GraphicsContext*)
|
||||
block();
|
||||
}
|
||||
|
||||
void ReleaseContext_Block_MakeCurrentOperation::release()
|
||||
{
|
||||
Block::release();
|
||||
}
|
||||
|
||||
|
||||
void ReleaseContext_Block_MakeCurrentOperation::operator () (GraphicsContext* context)
|
||||
{
|
||||
if (!context) return;
|
||||
|
Loading…
Reference in New Issue
Block a user