[Python-Dev] Weak references: dereference notification

Gustavo J. A. M. Carneiro gjc at inescporto.pt
Wed Nov 9 18:52:19 CET 2005


Qua, 2005-11-09 às 09:23 -0800, Guido van Rossum escreveu:
> > > Gustavo J. A. M. Carneiro wrote:
> > > >   I have come across a situation where I find the current weak
> > > > references interface for extension types insufficient.
> > > >
> > > >   Currently you only have a tp_weaklistoffset slot, pointing to a
> > > > PyObject with weak references.  However, in my case[1] I _really_ need
> > > > to be notified when a weak reference is dereferenced.
> 
> I find reading through the bug discussion a bit difficult to
> understand your use case. Could you explain it here? If you can't
> explain it you certainly won't get your problem solved! :-)

  This is a typical PyObject wrapping C object (GObject) problem.  Both
PyObject and GObject have independent reference counts.  For each
GObject there is at most one PyObject wrapper.

  When the refcount on the wrapper drops to zero, tp_dealloc is called.
In tp_dealloc, and if the GObject refcount is > 1, I do something
slightly evil: I 'resurect' the PyObject (calling PyObject_Init), create
a weak reference to the GObject, and drop the "strong" reference.  I
call this a 'hibernation state'.


  Now the problem.  Suppose the user had a weak ref to the PyObject:

 	1- At certain point in time, when the wrapper is in hibernation state,
the user calls the weak ref
	2- It gets a PyObject that contains a weak reference to the GObject;
	3- Now suppose whatever was holding the GObject ref drops its
reference, which was the last one, and the GObject dies;
	4- Now the user does something with the PyObject obtained through the
weakref -> invalid memory access.

  The cause for the problem is that between steps 2 and 3 the wrapper
needs to change the weak reference to the GObject to a strong one.
Unfortunately, I don't get any notification that 2 happened.

  BTW, I fixed this problem in the mean time with a bit more of slightly
evil code.  I override tp_call of the standard weakref type :-P

[...]
> > and weakref.ref was smart enough to lookup this type and use it, only
> > _then_ it could work.
> 
> Looks what you're looking for is a customizable factory fuction.

  Sure, if weakref.ref could be such a factory, and could take "advice"
on what type of weakref to use for each class.

  Regards.

-- 
Gustavo J. A. M. Carneiro
<gjc at inescporto.pt> <gustavo at users.sourceforge.net>
The universe is always one step beyond logic.



More information about the Python-Dev mailing list