The reason to call the original DESTROY is so that if a future version of
IO::All adds logic to the DESTROY, you will still run that new code.  While
still running the code that you know you need to run.

In fact I would suggest the following instead:

use IO::All;
{
  no warnings 'redefine';
  my $orig_destroy = *IO::All::DESTROY{CODE};
  sub IO::All::DESTROY {
    my $self = shift;
    no warnings;
    untie *$self if tied *$self;
    $orig_destroy->($self, @_) if $orig_destroy;
  }
}

Now the custom code that you run is limited to what you are afraid that
their DESTROY gets wrong.

(Note that my original version had a bug.  I said IO::ALL::DESTROY when it
needed to be IO::All::DESTROY.)

On Tue, Dec 13, 2016 at 1:11 PM, Duane Bronson <[email protected]>
wrote:

> The original DESTROY had the leaky code (see the commented #unless below),
> so I don't think it would help to keep calling it.  My replacement DESTROY
> is a copy/paste of the one in IO/All.pm with the bad lines commented out.
>
> I haven't really been able to find the implementation of the version
> class.  I hoped it was just missing a destructor that I could copy from a
> newer perl and conditionally add it to the package.
>
> Yes, our product is using scientific linux 6.3 which uses perl 5.10.x, and
> our customers and QA don't like hot fixes that replace nearly every RPM.
> In fact, they would probably prefer the memory leak.
>
> Duane
>
> On Dec 13, 2016, at 2:03 PM, Ben Tilly <[email protected]> wrote:
>
> There is always a risk when working with the internals of another module.
> I would minimize that risk by making sure that the DESTROY that you are
> replacing always runs.  Just in case something gets added to it.  And
> capture the reference to it in a way that will notice if DESTROY is
> eliminated.
>
> Like this:
>
> use IO::All;
> {
>   no warnings 'redefine';
>   my $orig_destroy = *IO::ALL::DESTROY{CODE};
>   sub IO::All::DESTROY {
>     my $self = shift;
>     $orig_destroy->($self, @_) if $orig_destroy;
>     no warnings;
>     untie *$self if tied *$self;
>     $self->close if $self->is_open;
>   }
> }
>
> On Tue, Dec 13, 2016 at 10:04 AM, Duane Bronson <[email protected]>
> wrote:
>
>> Mongers,
>>
>> I've been trying to track down a memory leak in a long running perl
>> script that uses IO::All to write a bunch of files every few seconds.  I
>> traced my leak back to IO::All which checks to make sure the version is at
>> least 5.8.0 before calling untie.  Pretty innocuous, imho.
>>
>> Here's an easy way to reproduce it.  In perl 5.10.1, this script causes
>> perl's memory to grow really big.  It appears to be fixed in later versions
>> of perl because there is no memory leak on my mac (perl 5.18.2).
>>
>> perl -E 'for $i (0..100_000_000) { 1 if ($^V) }'
>> and
>> perl -E '$foo = version->new(v1.2.3); for $i (0..100_000_000) { 1 if
>> ($foo) }'
>> and (slower)
>> perl -E 'use IO::All; for $i (0..100_000_000) { "file contents" >
>> io("/tmp/filename") }'
>>
>> Is there a way of fixing my script so I can still use IO::All and not
>> have a memory leak?  Here is one way, but I suspect there are better
>> methods that won't break with a future version of IO::All.
>>
>> use IO::All;
>> {
>>   no warnings 'redefine';
>>   sub IO::All::DESTROY {
>>     my $self = shift;
>>     no warnings;
>>     #unless ( $^V and $^V lt v5.8.0 ) {
>>         untie *$self if tied *$self;
>>     #}
>>     $self->close if $self->is_open;
>>   }
>> }
>>
>> Thanks,
>> Duane
>>
>>
>>
>> Duane Bronson
>> [email protected] <mailto:[email protected]>
>> http://www.nerdlogic.com/ <http://www.nerdlogic.com/>
>> 5 Goden St.
>> Belmont, MA 02478
>> 617.515.2909
>>
>>
>>
>>
>>
>> _______________________________________________
>> Boston-pm mailing list
>> [email protected]
>> http://mail.pm.org/mailman/listinfo/boston-pm
>
>
>
>
> *Duane Bronson*
> [email protected]
> http://www.nerdlogic.com/
> 5 Goden St.
> Belmont, MA 02478
> 617.515.2909
>
>
>
>
>

_______________________________________________
Boston-pm mailing list
[email protected]
http://mail.pm.org/mailman/listinfo/boston-pm

Reply via email to