[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