I think this is related to the rogue DESTROY bug that I reported earlier 
(where DESTROY is called too many times).  This time, DESTROY is not called 
often enough.

Unfortunately, I have _not_ been able to reduce this to a simple 
case.  However, the simple case shows a difference that might explain the 
difference in behaviour that I found.

Basically, in some cases DESTROY is not being called if the reference to 
the object is stored in a global, rather than in a lexical.

=== destroyFoo ====================================================
package Foo;
sub new { bless {},shift }
sub DESTROY { warn "in Foo::DESTROY for $_[0]"; }

package main;
$global = Foo->new;
our $our = Foo->new;
my $lexical = Foo->new;
===================================================================

If I run this, I get:

  $ perl destroyFoo
  in Foo::DESTROY for Foo=HASH(0x8125fe8) at destroyFoo line 3.
  in Foo::DESTROY for Foo=HASH(0x8125ed4) at destroyFoo line 3 during 
global destruction.
  in Foo::DESTROY for Foo=HASH(0x8125fb8) at destroyFoo line 3 during 
global destruction.

Please note that the lexical is destroyed before global destruction (I know 
it's the lexical, because that's the only line you'll see if you take out 
the global objects).

Since the other problem with the rogue DESTROY also happens during global 
destruction, these two may be related.  For the record, I checked whether 
DESTROY was being called at all (even as a rogue DESTROY), but that was not 
the case.

Another bug that _may_ be related, is the threads->tid bug being reported 
incorrectly in DESTROY when threading (tid being the one of the thread 
joining the thread).


The code that _does_ show the problem consistently, is in the test-suite 
for Thread::Pool::Resolve (soon on CPAN).  The test code is basically:

========================================================================
use Storable qw(retrieve);
my $ip2domain = retrieve( 'ip2domain' ); # load database with dummy DNS info

sub gethostbyaddr { sleep( rand(2) ); $ip2domain->{$_[0]} }

use Thread::Pool::Resolve;
$resolve = Thread::Pool::Resolve->new( {resolver => \&gethostbyaddr} );
$resolve->read;
========================================================================

alternatives for the last two lines that _do_ work, are:

========================================================================
my $resolve = Thread::Pool::Resolve->new( {resolver => \&gethostbyaddr} );
$resolve->read;
========================================================================

and:

========================================================================
Thread::Pool::Resolve->new( {resolver => \&gethostbyaddr} )->read;
========================================================================


Hope this helps anyone.  This again cost me most of today to figure out...  ;-(


Liz

Reply via email to