(ui): visuOgre/SNegato3D::setvisible() freeze in ExRegistration
Summary
There a dead lock, or more probably an infinite signal/slot loop when setting the visibility of SNegato3D.
Steps to reproduce
ninja EXRegistration
./bin/exregistration
- click on
Load image
-
freeze
Dev environment
- OS: Linux
- CMake version: not relevant
- Compiler: not relevant
- Build type: not relevant
- Commit: febad064
Possible fixes
Replace SNegato3D::setVisible(bool _visible) with:
void SNegato3D::setVisible(bool _visible)
{
// True if the visibility need to be propagated
bool visibilityChanged = false;
using VisModSigType = ::fwData::Image::VisibilityModifiedSignalType;
std::shared_ptr<VisModSigType> visModSig;
{
const auto image = this->getLockedInOut< ::fwData::Image >(s_IMAGE_INOUT);
const auto visibility = image->getField<::fwData::Boolean>(s_VISIBILITY_FIELD);
visibilityChanged = !visibility || visibility->getValue() != _visible;
if(visibilityChanged)
{
image->setField(s_VISIBILITY_FIELD, ::fwData::Boolean::New(_visible));
visModSig = image->signal<VisModSigType>(::fwData::Image::s_VISIBILITY_MODIFIED_SIG);
}
}
if(visibilityChanged)
{
const ::fwCom::Connection::Blocker blocker(visModSig->getConnection(this->slot(s_UPDATE_VISIBILITY_SLOT)));
this->setPlanesOpacity();
visModSig->asyncEmit(_visible);
}
}
This should fixe the problem, BUT:
- it's a change of behavior with possible side effect as
setVible(true)
called twice will only really do something the first time. - The code in itself is weird: the inout image ownership is taken by the SNegato3d and I don't think this is right that the SNegato3D modify a property of a shared image object. If we have more than one SNegato3d, with the same image, the signal/slot looping is guaranted.
setVisible()
should only affect SNegato3D displaying, not the data object.
I'm not sure it is the right time to do a refactor of this widely used code, so feel free to comment