From bada884342efc0d065d4dcb0f7a800a39a740a6e Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Wed, 23 Jan 2013 17:38:28 +0000 Subject: [PATCH] From Pjotr Svetachov, "when you restart threading with startThreading/stopThreading the _drawQueue and _availableQueue are not reset properly. This can lead to a deadlock when threading is started again. So before threading is started again the queues must be reset. This deadlock is also reported earlier by someone else in here: http://forum.openscenegraph.org/viewtopic.php?p=43415#43415" --- include/osgViewer/Renderer | 5 +++++ src/osgViewer/Renderer.cpp | 14 ++++++++++++++ src/osgViewer/ViewerBase.cpp | 1 + 3 files changed, 20 insertions(+) diff --git a/include/osgViewer/Renderer b/include/osgViewer/Renderer index 46b75846e..c2b7c328c 100644 --- a/include/osgViewer/Renderer +++ b/include/osgViewer/Renderer @@ -69,6 +69,8 @@ class OSGVIEWER_EXPORT Renderer : public osg::GraphicsOperation virtual void release(); + virtual void reset(); + /** Force update of state associated with cameras. */ void setCameraRequiresSetUp(bool flag); bool getCameraRequiresSetUp() const; @@ -101,6 +103,9 @@ class OSGVIEWER_EXPORT Renderer : public osg::GraphicsOperation /** Release any thread waiting on the queue, even if the queue is empty. */ void release(); + /** Reset to fefault state (_isReleased = false)*/ + void reset(); + /** Take a SceneView from the queue. Can return 0 if release() is called when the queue is empty. */ osgUtil::SceneView* takeFront(); diff --git a/src/osgViewer/Renderer.cpp b/src/osgViewer/Renderer.cpp index ae36229d3..2de31babe 100644 --- a/src/osgViewer/Renderer.cpp +++ b/src/osgViewer/Renderer.cpp @@ -304,6 +304,13 @@ void Renderer::ThreadSafeQueue::release() _cond.broadcast(); } +void Renderer::ThreadSafeQueue::reset() +{ + OpenThreads::ScopedLock lock(_mutex); + _queue.clear(); + _isReleased = false; +} + osgUtil::SceneView* Renderer::ThreadSafeQueue::takeFront() { OpenThreads::ScopedLock lock(_mutex); @@ -902,6 +909,13 @@ void Renderer::release() _drawQueue.release(); } +void Renderer::reset(){ + _availableQueue.reset(); + _availableQueue.add(_sceneView[0].get()); + _availableQueue.add(_sceneView[1].get()); + _drawQueue.reset(); +} + void Renderer::setCameraRequiresSetUp(bool flag) { for (int i = 0; i < 2; ++i) diff --git a/src/osgViewer/ViewerBase.cpp b/src/osgViewer/ViewerBase.cpp index facf3b841..7a2029d92 100644 --- a/src/osgViewer/ViewerBase.cpp +++ b/src/osgViewer/ViewerBase.cpp @@ -336,6 +336,7 @@ void ViewerBase::startThreading() { renderer->setGraphicsThreadDoesCull(graphicsThreadsDoesCull); renderer->setDone(false); + renderer->reset(); ++numViewerDoubleBufferedRenderingOperation; } }