Skip Menu |

This queue is for tickets about the Template-Toolkit CPAN distribution.

Report information
The Basics
Id: 62045
Status: resolved
Priority: 0/
Queue: Template-Toolkit

People
Owner: Nobody in particular
Requestors: hiratara [...] cpan.org
Cc:
AdminCc:

Bug Information
Severity: Important
Broken in: 2.22
Fixed in: (no value)



Subject: Memory leak in Plugin::Filter
Hi. I found a memory leak and reported. I used following simple script to find the problem. use strict; use warnings; use Template; for my $l (1 .. 1000) { my $tpl = Template->new(PLUGIN_BASE => 'test'); $tpl->context->plugin('simple', []); warn `ps -o rss= -p $$` if $l % 10 == 0; } I read https://rt.cpan.org/Public/Bug/Display.html?id=46691 and understood my patch had been reverted. So I wrote another one. How is this patch? All tests in the t/ directory are passed and there are no memory leaks. Since I thought only the context should have the filter's reference, I weakened another references.
Subject: for_tt-2.22.patch
diff --git a/lib/Template/Plugin/Filter.pm b/lib/Template/Plugin/Filter.pm index 420cc94..bb3de9d 100644 --- a/lib/Template/Plugin/Filter.pm +++ b/lib/Template/Plugin/Filter.pm @@ -48,6 +48,7 @@ sub new { _ARGS => \@args, _CONFIG => $config, }, $class; + weaken($self->{_CONTEXT}); return $self->init($config) || $class->error($self->error()); @@ -62,31 +63,29 @@ sub init { sub factory { my $self = shift; - my $this = $self; - - # This causes problems: https://rt.cpan.org/Ticket/Display.html?id=46691 - # If the plugin is loaded twice in different templates (one INCLUDEd into - # another) then the filter gets garbage collected when the inner template - # ends (at least, I think that's what's happening). So I'm going to take - # the "suck it and see" approach, comment it out, and wait for someone to - # complain that this module is leaking memory. - - # weaken($this); if ($self->{ _DYNAMIC }) { - return $self->{ _DYNAMIC_FILTER } ||= [ sub { + return $self->{ _DYNAMIC_FILTER } if $self->{ _DYNAMIC_FILTER }; + + my $dynamic_filter = [ sub { my ($context, @args) = @_; my $config = ref $args[-1] eq 'HASH' ? pop(@args) : { }; return sub { - $this->filter(shift, \@args, $config); + $self->filter(shift, \@args, $config); }; }, 1 ]; + weaken($self->{ _DYNAMIC_FILTER } = $dynamic_filter); + return $dynamic_filter; } else { - return $self->{ _STATIC_FILTER } ||= sub { - $this->filter(shift); + return $self->{ _STATIC_FILTER } if $self->{ _STATIC_FILTER }; + + my $static_filter = sub { + $self->filter(shift); }; + weaken($self->{ _STATIC_FILTER } = $static_filter); + return $static_filter; } }
I also experience leaks with that patch. Only the original one ('weaken $this') works for me.
Ticket migrated to github as https://github.com/abw/Template2/issues/152