Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 19 additions & 0 deletions lib/Mail/SpamAssassin.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1661,6 +1661,25 @@ sub finish {
$self->call_plugins("finish_tests", { conf => $self->{conf},
main => $self });

# clean up eval-plugin glue (register_plugin_eval_glue()) and any
# plugin-registered generated rule methods (register_generated_rule_method()),
# left in place across all messages processed by this session -- see
# the comment in PerMsgStatus::finish() for why these aren't cleaned up
# per-message. register_plugin_eval_glue() pushes bare names (defined in
# the PerMsgStatus package); register_generated_rule_method() pushes
# fully-qualified ones -- qualify bare names here since, unlike
# PerMsgStatus::finish()'s original cleanup loop, this code doesn't run
# in the PerMsgStatus package itself.
{ no strict 'refs';
foreach my $method (@Mail::SpamAssassin::PerMsgStatus::TEMPORARY_METHODS) {
my $fqname = $method =~ /::/ ? $method
: "Mail::SpamAssassin::PerMsgStatus::$method";
undef &{$fqname} if defined &{$fqname};
}
}
@Mail::SpamAssassin::PerMsgStatus::TEMPORARY_METHODS = ();
%Mail::SpamAssassin::PerMsgStatus::TEMPORARY_EVAL_GLUE_METHODS = ();

$self->{plugins}->finish(); delete $self->{plugins};

if ($self->{bayes_scanner}) {
Expand Down
16 changes: 8 additions & 8 deletions lib/Mail/SpamAssassin/PerMsgStatus.pm
Original file line number Diff line number Diff line change
Expand Up @@ -1959,14 +1959,14 @@ sub finish {

$self->report_unsatisfied_actions();

# Clean up temporary methods
foreach my $method (@TEMPORARY_METHODS) {
if (defined &{$method}) {
undef &{$method};
}
}
@TEMPORARY_METHODS = (); # clear for next time
%TEMPORARY_EVAL_GLUE_METHODS = ();
# Note: @TEMPORARY_METHODS/%TEMPORARY_EVAL_GLUE_METHODS (eval-plugin glue
# generated by register_plugin_eval_glue(), and any methods a plugin
# registered via register_generated_rule_method()) are intentionally NOT
# cleaned up here. They're static per-config, safe to reuse for every
# message scanned by this process -- same lifetime as Check.pm's own
# compiled rule subs. Cleaning them up per-message forced eval-plugin
# glue to be eval()-recompiled on every single message. They're cleaned
# up once at session end, in Mail::SpamAssassin::finish().

# Delete out all of the members of $self. This will remove any direct
# circular references and let the memory get reclaimed while also being more
Expand Down