[vtk-developers] Patch to vtkWrapPython.c to make wrapped Python code GIL-friendly
Sander Niemeijer
niemeijer at science-and-technology.nl
Mon Jul 4 13:09:13 EDT 2005
On maandag, jul 4, 2005, at 18:03 Europe/Amsterdam, Charl P. Botha
wrote:
> Hi there Sander,
>
> On 7/1/05, Sander Niemeijer <niemeijer at science-and-technology.nl>
> wrote:
>> The point is, I have already been bitten by the current behaviour of
>> vtkPythonCommand::Execute.
>> When in our wxPython/VTK application a vtkPytonCommand::Execute is
>> called to run a Python method (that was registered as observer on a
>> VTK
>> object) we receive a SEGFAULT:
>> PyFrame_New (tstate=0x0, code=0x43997a20, globals=0x4187c3e4,
>> locals=0x0)
>> at Objects/frameobject.c:540
>> 540 PyFrameObject *back = tstate->frame;
>> The tstate (current Python thread state) is NULL, which should never
>> happen.
>> I was first able to 'fix' this by just building everything (i.e.
>> Python, VTK, wxPython) without thread support, but I recently
>> discovered the PyGILState API and was able to fix our crash by adding
>> PyGILState_Ensure() and PyGILState_Release() calls to the
>> vtkPythonCommand:Execute function.
>
> I haven't ever seen this specific behaviour before, but I think I know
> why.
Well, please let me know. I might be able to verify it for you.
> Do you perhaps have a small Python test case with which I can
> reproduce this segfault on a stock VTK CVS build?
This will not be that easy since we are not using the
wxVTKRenderWindowInteractor anymore but a C++ solution with our own
Python wrapping. I can however try to explain the scenario.
First something about our wxVTKWindow implementation:
The wxPython-VTK bridge we are currently using is a C++ wxVTKWindow
class that is a derivative of wxWindow (or wxGLCanvas for GTK). Just as
the Python wxVTKRenderWindowInteractor one of the members is a
vtkGenericRenderWindowInteractor, but instead of remapping all
vtkRenderWindowInteractor functions inside the vtk widget class (the
'lambda t=self._Iren: t' trick) we provide access to the interactor via
the method wxVTKWindow::GetRenderWindowInteractor(). The event mapping
in wxVTKWindow is however identical to the one in
wxVTKRenderWindowInteractor.
We map the wxVTKWindow class to Python using SWIG (since the
wxVTKWindow inherits from wxWindow/wxGLCanvas this mapping is based on
the way wxPython does its Python mappings). The only VTK specific parts
in this mapping is the handling of the return values for
::GetRenderWindow() and ::GetRenderWindowInteractor() which is done
with:
---
%typemap(out) vtkRenderWindow * {
$result = vtkPythonGetObjectFromPointer((vtkObjectBase *)$1);
}
%typemap(out) vtkRenderWindowInteractor * {
$result = vtkPythonGetObjectFromPointer((vtkObjectBase *)$1);
}
---
The big difference between our wxVTKWindow approach and the
wxVTKRenderWindowInteractor is that in our case the
vtkGenericRenderWindowInteractor is created in the C++ domain and not
in the Python domain. And this may be the reason why I am seeing the
segfault.
The trigger for the crash is the following observer that is created in
a wx.Frame derivate:
self.vtkwidget.GetRenderWindowInteractor().AddObserver('CharEvent',
self.OnVTKChar)
# the vtkwidget is an instance of wxVTKWindow
As soon as I hit a key (with focus on the VTK renderwindow of course)
the crash happens.
By the way, the reason I created a C++ version of the wxPython-VTK
binding is so I could have better control over the initialization and
finalization (especially the latter; I heard there was a Finalize()
method introduced lately that should help improve the finalization
process, but I haven't tried this yet). And also debugging is much
easier this way (I still am struggling with the GTK 2.0 binding for
instance and keep getting BadWindow errors (using wxPython 2.6.1.0)).
Best regards,
Sander
More information about the vtk-developers
mailing list