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