[Python-Dev] Re: GC and ExtensionClass - a summary of the problem and a workaround
James Henstridge
james@daa.com.au
Thu, 17 May 2001 15:18:23 +0800 (WST)
On Thu, 17 May 2001 skip@pobox.com wrote:
>
> Over the past couple days I've included python-dev on various messages in an
> ongoing thread about a segmentation violation I was getting with the new
> PyGtk2 wrappers. With some excellent assistance from the GC maestro, Neil
> Schemenauer, I finally know what's going on and I have a simple workaround
> that lets me get back to work. Here's a summary of the problem.
>
> When defining ExtensionClass types, you need to create and initialize a
> PyExtensionClass struct. It looks something like so:
>
> PyExtensionClass PyGtkTreeSortable_Type = {
> PyObject_HEAD_INIT(NULL)
> 0, /* ob_size */
> "GtkTreeSortable", /* tp_name */
> sizeof(PyPureMixinObject), /* tp_basicsize */
> ...
> };
>
> Note that the parameter to the PyObject_HEAD_INIT macro is NULL. It would
> normally be the address of a type object (e.g. &PyType_Type). However, Jim
> Fulton pointed out that on Windows you can't get the address of &PyType_Type
> object at compile time. Accordingly, ExtensionClass provides a
> PyExtensionClass_Export macro whose responsibility is, in part, to set the
> ob_type field appropriately at runtime. (I'm not sure why this Windows nit
> doesn't afflict other type declarations like PyTuple_Type. I'm sure others
> will know why. I just accept Jim's word as gospel and move on...)
Well, for Extension Classes, PyType_Type is not correct either. And
because ExtensionClass is loaded at runtime, we can't set the ob_type
field in the initialiser even on Unix systems.
>
> A problem arises if the garbage collector runs while the module
> initialization function is running, but before all the ob_type fields have
> been assigned their correct values. In this case, a one-element tuple
> representing the bases of a particular PyGtk extension class was traversed
> by the garbage collector.
>
> The workaround turns out to be exceedingly simple:
>
> import gc
> gc.disable()
> import gtk
> gc.enable()
>
> I can handle doing that from Python code for the time being and will leave
> it up to others to decide how, if at all, ExtensionClass should be changed
> to correct the problem.
Thanks for debugging this problem Skip. If we don't find a correct
solution to the problem, I can put the gc disable/enable calls inside the
gtk/__init__.py module.
James.