CRASH: Invoking VolumeMapperComputeGradientsStartEvent and VolumeMapperComputeGradientsEndEvent evens are not thread safe
This issue was created automatically from an original Mantis Issue. Further discussion may take place here.
At file: vtkFixedPointVolumeRayCastMapper.cxx at method: void vtkFixedPointVolumeRayCastMapperComputeCS1CGradients(...)
This method deliberately calls the me->InvokeEvent( vtkCommand::VolumeMapperComputeGradientsStartEvent, NULL ); me->InvokeEvent( vtkCommand::VolumeMapperComputeGradientsEndEvent, NULL ); methods to inform the application layer that the events VolumeMapperComputeGradientsStartEvent VolumeMapperComputeGradientsEndEvent are about to happen.
However the vtkFixedPointVolumeRayCastMapperComputeCS1CGradients method is designed to be run on multiple threads/processor but it uses the vtkSubjectHelper::InvokeEvent method which is not thread safe.
In our case VTK created 3 threads for gradient computation. During the computation and during the above InvokeEvent calls the vtkObjectBase::ReferenceCount member was compromised inside the our subclassed vtkCommand instance. This means that the reference count decreased to 0 and the vtkCommand deleted while there were still references for it. After a while the framework dereferenced that deleted class --> it lead to crash
Solution:
VTK 5.2.0 as been patched in order to avoid the InvokeEvent from multiple threads. The patch consist of calling the InvokeEvent methods right before thread creation (vtkCommand::VolumeMapperComputeGradientsStartEvent) and right after the thread exit (vtkCommand::VolumeMapperComputeGradientsEndEvent) These takes place at file vtkFixedPointVolumeRayCastMapper.cxx at method vtkFixedPointVolumeRayCastMapper::ComputeGradients
Note:
The other call for me->InvokeEvent( vtkCommand::VolumeMapperComputeGradientsProgressEvent, args ); has succeeded without such a problem because it was fired in case of: thread_id == 0 which was on purpose, I presume.