From a53308f7e84d468a7484d2b1e7643865cfee0383 Mon Sep 17 00:00:00 2001 From: Robert Osfield Date: Fri, 23 Dec 2011 17:34:07 +0000 Subject: [PATCH] Gunnar Holm, "After upgrading from 2.8.3 to 3.0.1 we experienced a lock in the Mutex functionality when using Terrain::setVerticalScale. This was caused by the following call sequence resulting in a lockup: void Terrain::setVerticalScale(float scale) CALLS dirtyRegisteredTiles(); void Terrain::dirtyRegisteredTiles(int dirtyMask) SETS LOCK OpenThreads::ScopedLock lock(_mutex); and CALLS (on every tile) setDirtyMask(dirtyMask); void TerrainTile::setDirtyMask(int dirtyMask) CALLS _terrain->updateTerrainTileOnNextFrame(this); void Terrain::updateTerrainTileOnNextFrame(TerrainTile* terrainTile) SETS LOCK OpenThreads::ScopedLock lock(_mutex); ******* PROBLEM - since lock has already been set! ******** The suggested fix submitted changes from using Mutex to ReentrantMutex. " --- include/osgTerrain/Terrain | 3 ++- src/osgTerrain/Terrain.cpp | 17 ++++++++--------- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/include/osgTerrain/Terrain b/include/osgTerrain/Terrain index 062bcf829..c7b3275ea 100644 --- a/include/osgTerrain/Terrain +++ b/include/osgTerrain/Terrain @@ -15,6 +15,7 @@ #define OSGTerrain 1 #include +#include #include @@ -109,7 +110,7 @@ class OSGTERRAIN_EXPORT Terrain : public osg::CoordinateSystemNode TerrainTile::BlendingPolicy _blendingPolicy; bool _equalizeBoundaries; - mutable OpenThreads::Mutex _mutex; + mutable OpenThreads::ReentrantMutex _mutex; TerrainTileSet _terrainTileSet; TerrainTileMap _terrainTileMap; TerrainTileSet _updateTerrainTileSet; diff --git a/src/osgTerrain/Terrain.cpp b/src/osgTerrain/Terrain.cpp index 8d153ee94..ee84c0f8d 100644 --- a/src/osgTerrain/Terrain.cpp +++ b/src/osgTerrain/Terrain.cpp @@ -44,7 +44,7 @@ Terrain::Terrain(const Terrain& ts, const osg::CopyOp& copyop): Terrain::~Terrain() { - OpenThreads::ScopedLock lock(_mutex); + OpenThreads::ScopedLock lock(_mutex); for(TerrainTileSet::iterator itr = _terrainTileSet.begin(); itr != _terrainTileSet.end(); @@ -96,7 +96,7 @@ void Terrain::traverse(osg::NodeVisitor& nv) typedef std::list< osg::ref_ptr > TerrainTileList; TerrainTileList tiles; { - OpenThreads::ScopedLock lock(_mutex); + OpenThreads::ScopedLock lock(_mutex); std::copy(_updateTerrainTileSet.begin(), _updateTerrainTileSet.end(), std::back_inserter(tiles)); _updateTerrainTileSet.clear(); } @@ -116,14 +116,14 @@ void Terrain::traverse(osg::NodeVisitor& nv) void Terrain::updateTerrainTileOnNextFrame(TerrainTile* terrainTile) { - OpenThreads::ScopedLock lock(_mutex); + OpenThreads::ScopedLock lock(_mutex); _updateTerrainTileSet.insert(terrainTile); } TerrainTile* Terrain::getTile(const TileID& tileID) { - OpenThreads::ScopedLock lock(_mutex); + OpenThreads::ScopedLock lock(_mutex); // OSG_NOTICE<<"Terrain::getTile("< lock(_mutex); + OpenThreads::ScopedLock lock(_mutex); TerrainTileMap::const_iterator itr = _terrainTileMap.find(tileID); if (itr == _terrainTileMap.end()) return 0; @@ -145,8 +145,7 @@ const TerrainTile* Terrain::getTile(const TileID& tileID) const void Terrain::dirtyRegisteredTiles(int dirtyMask) { - OpenThreads::ScopedLock lock(_mutex); - + OpenThreads::ScopedLock lock(_mutex); for(TerrainTileSet::iterator itr = _terrainTileSet.begin(); itr != _terrainTileSet.end(); ++itr) @@ -160,7 +159,7 @@ void Terrain::registerTerrainTile(TerrainTile* tile) { if (!tile) return; - OpenThreads::ScopedLock lock(_mutex); + OpenThreads::ScopedLock lock(_mutex); if (tile->getTileID().valid()) { @@ -179,7 +178,7 @@ void Terrain::unregisterTerrainTile(TerrainTile* tile) { if (!tile) return; - OpenThreads::ScopedLock lock(_mutex); + OpenThreads::ScopedLock lock(_mutex); if (tile->getTileID().valid()) {