Commit e98462d2 authored by Sebastian Eichelbaum's avatar Sebastian Eichelbaum
Browse files

[CHANGE] - access to WModuleFactory in a unsafe (regarding threads) manner....

[CHANGE] - access to WModuleFactory in a unsafe (regarding threads) manner. Fixed this. Same Problem for WPropertyVariable -> i'll fix this later
parent 73ee0ba2
......@@ -192,12 +192,12 @@ public:
/**
* A set of constraints applied on this property.
*/
constraintContainer m_constraints;
constraintContainer m_constraints; //TODO(ebaum): not thread-safe and PUBLIC!!!??. Replace with WSharedObject
/**
* The iterator used to go through the set
*/
typedef typename constraintContainer::const_iterator constraintIterator;
typedef typename constraintContainer::const_iterator constraintIterator; //TODO(ebaum): not thread-safe. Replace with WSharedObject
/**
* Alias for min constraints. It is an alias for convenience.
......@@ -230,8 +230,9 @@ public:
* Returns all the current constraints of a WPropertyVariable for copy purpose
*
* \return the condition.
*
*/
constraintContainer getConstraints();
constraintContainer getConstraints(); //TODO(ebaum): not thread-safe. Replace with WSharedObject
/**
* Gets the condition, which gets notified whenever the list of constraints changes. It is notified AFTER the write lock has been released so
......@@ -372,7 +373,7 @@ private:
template< typename T >
typename WPropertyVariable<T>::constraintContainer WPropertyVariable<T>::getConstraints()
{
return m_constraints;
return m_constraints; //TODO(ebaum): not thread-safe. replace with WSharedObject
}
template < typename T >
......
......@@ -51,5 +51,18 @@ protected:
private:
};
template < typename T >
WSharedAssociativeContainer< T >::WSharedAssociativeContainer():
WSharedObject< T >()
{
// init members
}
template < typename T >
WSharedAssociativeContainer< T >::~WSharedAssociativeContainer()
{
// clean up
}
#endif // WSHAREDASSOCIATIVECONTAINER_H
......@@ -87,16 +87,17 @@ WQtConfigWidget::~WQtConfigWidget()
void WQtConfigWidget::getAvailibleModuleNames()
{
WModuleFactory::WModulePrototypeSet prototypes = WModuleFactory::getModuleFactory()->getAvailiblePrototypes();
WModuleFactory::WModulePrototypeSet::iterator itr;
WModuleFactory::PrototypeSharedContainerType::WSharedAccess pa = WModuleFactory::getModuleFactory()->getAvailablePrototypes();
m_moduleNames.clear();
for ( itr = prototypes.begin(); itr != prototypes.end(); ++itr )
pa->beginRead();
for ( WModuleFactory::PrototypeContainerConstIteratorType itr = pa->get().begin(); itr != pa->get().end(); ++itr )
{
m_moduleNames.push_back( ( *itr )->getName() );
}
pa->endRead();
}
void WQtConfigWidget::updatePropertyGroups( boost::shared_ptr< WProperties > properties, std::string groupName, bool fromConfig )
{
// Here we assume we already registered our properties
......
......@@ -70,7 +70,9 @@
// factory instance as singleton
boost::shared_ptr< WModuleFactory > WModuleFactory::m_instance = boost::shared_ptr< WModuleFactory >();
WModuleFactory::WModuleFactory()
WModuleFactory::WModuleFactory():
m_prototypes(),
m_prototypeAccess( m_prototypes.getAccessObject() )
{
// initialize members
}
......@@ -86,51 +88,51 @@ void WModuleFactory::load()
WLogger::getLogger()->addLogMessage( "Loading Modules", "ModuleFactory", LL_INFO );
// operation must be exclusive
boost::unique_lock< boost::shared_mutex > lock = boost::unique_lock< boost::shared_mutex >( m_prototypesLock );
m_prototypeAccess->beginWrite();
// currently the prototypes are added by hand. This will be done automatically later.
m_prototypes.insert( boost::shared_ptr< WModule >( new WMTemplate() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMBoundingBox() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMData() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMNavSlices() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMDeterministicFTMori() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberDisplay() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberCulling() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberClustering() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMCoordinateSystem() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMMarchingCubes() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMDistanceMapIsosurface() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMDistanceMap() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMApplyMask() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMGaussFiltering() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMHud() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMEEGView() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMVoxelizer() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMTriangleMeshRenderer() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMDirectVolumeRendering() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMWriteNIfTI() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMDataTypeConversion() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMConnectomeView() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMClusterParamDisplay() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberSelection() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMSurfaceParticles() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMClusterSlicer() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMVectorPlot() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMGeometryGlyphs() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMArbitraryRois() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMMeshReader() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMFiberTransform() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMLIC() ) );
m_prototypes.insert( boost::shared_ptr< WModule >( new WMSuperquadricGlyphs() ) );
lock.unlock();
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMTemplate() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMBoundingBox() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMData() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMNavSlices() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMDeterministicFTMori() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMFiberDisplay() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMFiberCulling() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMFiberClustering() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMCoordinateSystem() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMMarchingCubes() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMDistanceMapIsosurface() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMDistanceMap() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMApplyMask() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMGaussFiltering() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMHud() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMEEGView() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMVoxelizer() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMTriangleMeshRenderer() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMDirectVolumeRendering() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMWriteNIfTI() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMDataTypeConversion() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMConnectomeView() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMClusterParamDisplay() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMFiberSelection() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMSurfaceParticles() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMClusterSlicer() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMVectorPlot() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMGeometryGlyphs() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMArbitraryRois() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMMeshReader() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMFiberTransform() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMLIC() ) );
m_prototypeAccess->get().insert( boost::shared_ptr< WModule >( new WMSuperquadricGlyphs() ) );
m_prototypeAccess->endWrite();
// for this a read lock is sufficient
boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );
m_prototypeAccess->beginRead();
// initialize every module in the set
std::set< std::string > names; // helper to find duplicates
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypes.begin(); listIter != m_prototypes.end();
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypeAccess->get().begin(); listIter != m_prototypeAccess->get().end();
++listIter )
{
WLogger::getLogger()->addLogMessage( "Loading module: \"" + ( *listIter )->getName() + "\"", "ModuleFactory", LL_INFO );
......@@ -145,7 +147,7 @@ void WModuleFactory::load()
initializeModule( ( *listIter ) );
}
slock.unlock();
m_prototypeAccess->endRead();
}
boost::shared_ptr< WModule > WModuleFactory::create( boost::shared_ptr< WModule > prototype )
......@@ -153,15 +155,15 @@ boost::shared_ptr< WModule > WModuleFactory::create( boost::shared_ptr< WModule
wlog::debug( "ModuleFactory" ) << "Creating new instance of prototype \"" << prototype->getName() << "\".";
// for this a read lock is sufficient
boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );
m_prototypeAccess->beginRead();
// ensure this one is a prototype and nothing else
if ( m_prototypes.count( prototype ) == 0 )
if ( m_prototypeAccess->get().count( prototype ) == 0 )
{
throw WPrototypeUnknown( "Could not clone module \"" + prototype->getName() + "\" since it is no prototype." );
}
slock.unlock();
m_prototypeAccess->endRead();
// call prototypes factory function
boost::shared_ptr< WModule > clone = boost::shared_ptr< WModule >( prototype->factory() );
......@@ -189,11 +191,11 @@ boost::shared_ptr< WModuleFactory > WModuleFactory::getModuleFactory()
const boost::shared_ptr< WModule > WModuleFactory::isPrototypeAvailable( std::string name )
{
// for this a read lock is sufficient
boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );
m_prototypeAccess->beginRead();
// find first and only prototype (ensured during load())
boost::shared_ptr< WModule > ret = boost::shared_ptr< WModule >();
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypes.begin(); listIter != m_prototypes.end();
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypeAccess->get().begin(); listIter != m_prototypeAccess->get().end();
++listIter )
{
if ( ( *listIter )->getName() == name )
......@@ -203,7 +205,7 @@ const boost::shared_ptr< WModule > WModuleFactory::isPrototypeAvailable( std::st
}
}
slock.unlock();
m_prototypeAccess->endRead();
return ret;
}
......@@ -244,10 +246,11 @@ std::vector< boost::shared_ptr< WApplyPrototypeCombiner > > WModuleFactory::getC
std::vector< boost::shared_ptr < WApplyPrototypeCombiner > > compatibles;
// for this a read lock is sufficient
boost::shared_lock< boost::shared_mutex > slock = boost::shared_lock< boost::shared_mutex >( m_prototypesLock );
m_prototypeAccess->beginRead();
// First, add all modules with no input connector.
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypes.begin(); listIter != m_prototypes.end(); ++listIter )
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypeAccess->get().begin(); listIter != m_prototypeAccess->get().end();
++listIter )
{
// get connectors of this prototype
std::set<boost::shared_ptr<WModuleInputConnector> > pcons = ( *listIter )->getInputConnectors();
......@@ -283,7 +286,8 @@ std::vector< boost::shared_ptr< WApplyPrototypeCombiner > > WModuleFactory::getC
// }
// go through every prototype
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypes.begin(); listIter != m_prototypes.end(); ++listIter )
for( std::set< boost::shared_ptr< WModule > >::iterator listIter = m_prototypeAccess->get().begin(); listIter != m_prototypeAccess->get().end();
++listIter )
{
// get connectors of this prototype
std::set<boost::shared_ptr<WModuleInputConnector> > pcons = ( *listIter )->getInputConnectors();
......@@ -312,7 +316,7 @@ std::vector< boost::shared_ptr< WApplyPrototypeCombiner > > WModuleFactory::getC
}
}
slock.unlock();
m_prototypeAccess->endRead();
// sort the compatibles
std::sort( compatibles.begin(), compatibles.end(), compatiblesSort );
......@@ -320,8 +324,8 @@ std::vector< boost::shared_ptr< WApplyPrototypeCombiner > > WModuleFactory::getC
return compatibles;
}
const WModuleFactory::WModulePrototypeSet WModuleFactory::getAvailiblePrototypes()
const WModuleFactory::PrototypeSharedContainerType::WSharedAccess WModuleFactory::getAvailablePrototypes() const
{
return m_prototypes;
return m_prototypeAccess;
}
......@@ -33,6 +33,7 @@
#include <boost/thread.hpp>
#include "../modules/data/WMData.h" // this is the ONLY module with a special meaning. Every one knowing the factory also knows this
#include "../common/WSharedAssociativeContainer.h"
#include "combiner/WApplyPrototypeCombiner.h"
#include "WModule.h"
......@@ -44,6 +45,31 @@ class WModuleFactory
friend class WModuleFactoryTest;
public:
/**
* For shortening: a type defining a shared set of WModule pointers.
*/
typedef std::set< boost::shared_ptr< WModule > > PrototypeContainerType;
/**
* Const iterator for the prototype set.
*/
typedef std::set< boost::shared_ptr< WModule > >::const_iterator PrototypeContainerConstIteratorType;
/**
* Iterator for the prototype set.
*/
typedef std::set< boost::shared_ptr< WModule > >::iterator PrototypeContainerIteratorType;
/**
* The alias for a shared container.
*/
typedef WSharedAssociativeContainer< PrototypeContainerType > PrototypeSharedContainerType;
/**
* Alias for the proper access object
*/
typedef PrototypeSharedContainerType::WSharedAccess PrototypeAccess;
/**
* Default constructor.
*/
......@@ -137,28 +163,27 @@ public:
*/
static void initializeModule( boost::shared_ptr< WModule > module );
typedef std::set< boost::shared_ptr< WModule > > WModulePrototypeSet;
/**
* Getter method for registered Prototypes
*
* \return set of availible Prototypes
*/
const WModulePrototypeSet getAvailiblePrototypes();
* Get access to all the prototypes.
*
* \return the access object to thread safe iterate.
*/
const PrototypeSharedContainerType::WSharedAccess getAvailablePrototypes() const;
protected:
/**
* The module prototypes available.
*/
WModulePrototypeSet m_prototypes;
PrototypeSharedContainerType m_prototypes;
/**
* The lock for the prototypes set.
*/
boost::shared_mutex m_prototypesLock;
PrototypeSharedContainerType::WSharedAccess m_prototypeAccess;
private:
/**
* Singleton instance of WModuleFactory.
*/
......
......@@ -93,15 +93,15 @@ void WMSuperquadricGlyphs::properties()
m_xPos = m_properties->addProperty( "X Pos of the slice", "Slice X position.", 80, m_propCondition );
m_yPos = m_properties->addProperty( "Y Pos of the slice", "Slice Y position.", 100, m_propCondition );
m_zPos = m_properties->addProperty( "Z Pos of the slice", "Slice Z position.", 80, m_propCondition );
m_xPos->setHidden( true );
/* m_xPos->setHidden( true );
m_yPos->setHidden( true );
m_zPos->setHidden( true );
m_zPos->setHidden( true );*/
m_xPos->setMin( 0 );
m_xPos->setMax( 160 );
m_xPos->setMax( 159 );
m_yPos->setMin( 0 );
m_yPos->setMax( 200 );
m_yPos->setMax( 199 );
m_zPos->setMin( 0 );
m_zPos->setMax( 160 );
m_zPos->setMax( 159 );
// Flags denoting whether the glyphs should be shown on the specific slice
m_showonX = m_properties->addProperty( "Show Sagittal", "Show vectors on sagittal slice.", true, m_propCondition );
......@@ -170,11 +170,13 @@ void WMSuperquadricGlyphs::moduleMain()
dataValid = false;
}
bool posChanged = m_xPos->changed() || m_yPos->changed() || m_zPos->changed();
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Handle changes
// data changes
if ( dataChanged && dataValid )
if ( ( dataChanged || posChanged ) && dataValid )
{
// The data is different. Copy it to our internal data variable:
debugLog() << "Received Data.";
......@@ -223,7 +225,13 @@ void WMSuperquadricGlyphs::moduleMain()
size_t y = ( i / grid->getNbCoordsX() ) % grid->getNbCoordsY();
size_t z = i / ( grid->getNbCoordsX() * grid->getNbCoordsY() );
if ( ( x != 80 ) )
size_t xP = m_xPos->get( true );
size_t yP = m_yPos->get( true );
size_t zP = m_zPos->get( true );
if ( !( ( x == xP ) ||
( y == yP ) ||
( z == zP ) ) )
continue;
// get position in space
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment