DESTROY issues

Marc Lehmann schmorp at schmorp.de
Sat Nov 10 17:25:59 CET 2012


On Sat, Nov 10, 2012 at 01:36:17PM +0100, Henrik Pauli <henrik.pauli at gmail.com> wrote:
> block the UI.  For certain reasons such as an ancient GTK+, I couldn't
> use Gtk's own libsoup for this but AnyEvent::HTTP seems to work just fine.

Good to hear.

> working well inside evals, and you pointed it out to me that the DIE
> handler was broken, so I did attempt to fix it and the problems are

And this time, you hit a desing bug in perl: when you reference an object in
perl then it isn't DESTROYed normally, because there are references to it.

Unfortunately, this is not always true: when perl has trouble destructing
objects for whatever reason (it's often not clear why, and has nothing to
do with cycles), then perl corrupts data structures by freeing objects
seemingly randomly.

For example, you (or Anyevent, or sth. else) might create this kind of an
object:

   my $self = bless { socket => new AnyEvent ...

And in your DESTROY, you want to do sth. to the socket:

   $self->{socket}->....

And this works by the normal expected rules of the language, but sometimes
perl destroys $self->{socket} before your object, and leaves a pointer to
some invalid object there, so you can't even check easily.

The only way around this is to fix perl (which the p5pers have no
intention of doing), adorn effetively *every* method call with a
complicated check for whether the object is still there, or live with it
somehow, by trying to destroy objects manually before exiting, if this is
even possible.

The trouble is that the code that fails is usually not the code
"responsible" for it, so it might be hard to understand why this happens,
and the rules on which perl corrupts the objects are not well documented
(and in fact change with every release).

> $api is instantiated once, and gets destroyed at the end.  I guess this
> is when this discrepancy happens about the destroying of the underlying
> AnyEvent::Handle.

Perl should simply have no business destroying the handle when your
code still uses it, or vice versa. It breaks the basic guarantee that
destructors are called when an object goes out of scope and makes
destructors useless, but only at the end of the program.

> I'm curious about what I could do to guard against it — maybe by
> manually destroying the handle before exiting, something along those
> lines.  So, any ideas?

Manually destroying problematic data structures will likely help if you
can identify the exact source (which seems likely in your case).

I, for one, will not adorn every method call with extra checks - to me,
this is insanity. I, too, run into these cases- rarely, but consistently,
and the only way I found to effectively deal with them is patching perl or
destroying the most likely candidates cleanly myself, since perl can't be
bothered to do it.

(As you can probably tell, I find this design bug frustrating myself :)

-- 
                The choice of a       Deliantra, the free code+content MORPG
      -----==-     _GNU_              http://www.deliantra.net
      ----==-- _       generation
      ---==---(_)__  __ ____  __      Marc Lehmann
      --==---/ / _ \/ // /\ \/ /      schmorp at schmorp.de
      -=====/_/_//_/\_,_/ /_/\_\



More information about the anyevent mailing list