Subject: | Memory leak in POE-Wheel-Run (Win32) |
There is a small memory leak with every new POE::Wheel::Run. To
reproduce run the attached script and observe the memory usage in the
windows task manager.
Subject: | wr_leak.pl |
#!/usr/bin/perl
use warnings;
use strict;
sub POE::Kernel::ASSERT_DEFAULT () { 1 }
use POE;
use POE::Wheel::Run;
use POE::Filter::Line;
POE::Session->create(
inline_states => {
_start => \&on_start,
_stop => sub { print "main done"; },
got_child_stdout => \&on_child_stdout,
got_child_stderr => \&on_child_stderr,
got_child_close => \&on_child_close,
got_child_signal => \&on_child_signal,
pulse => \&pulse,
event_sigint => sub {
warn "Shutting down gracefully...\n";
$_[KERNEL]->sig_handled();
$_[KERNEL]->alarm_remove_all();
$_[HEAP]->{done} = 1;
return 0;
},
}
);
POE::Kernel->run();
exit 0;
sub on_start {
$_[KERNEL]->sig( INT => 'event_sigint' );
$_[KERNEL]->delay( pulse => 1);
}
# Wheel event, including the wheel's ID.
sub on_child_stdout {
my ($stdout_line, $wheel_id) = @_[ARG0, ARG1];
my $child = $_[HEAP]{children_by_wid}{$wheel_id};
print "pid ", $child->PID, " STDOUT: $stdout_line\n";
}
# Wheel event, including the wheel's ID.
sub on_child_stderr {
my ($stderr_line, $wheel_id) = @_[ARG0, ARG1];
my $child = $_[HEAP]{children_by_wid}{$wheel_id};
print "pid ", $child->PID, " STDERR: $stderr_line\n";
}
# Wheel event, including the wheel's ID.
sub on_child_close {
my $wheel_id = $_[ARG0];
my $child = delete $_[HEAP]{children_by_wid}{$wheel_id};
# May have been reaped by on_child_signal().
unless (defined $child) {
print "wid $wheel_id closed all pipes.\n";
return;
}
print "pid ", $child->PID, " closed all pipes.\n";
delete $_[HEAP]{children_by_pid}{$child->PID};
$_[KERNEL]->yield( 'pulse' ) unless $_[HEAP]->{done};
}
sub on_child_signal {
print "pid $_[ARG1] exited with status $_[ARG2].\n";
my $child = delete $_[HEAP]{children_by_pid}{$_[ARG1]};
#$_[KERNEL]->sig_child($_[ARG1]);
# May have been reaped by on_child_close().
return unless defined $child;
delete $_[HEAP]{children_by_wid}{$child->ID};
$_[KERNEL]->yield( 'pulse' ) unless $_[HEAP]->{done};
}
sub pulse {
my $child;
eval {
$child = POE::Wheel::Run->new(
Program => 'perl -e "sleep 2"',
StdoutEvent => "got_child_stdout",
StderrEvent => "got_child_stderr",
CloseEvent => "got_child_close",
);
};
if ($@) {
warn $@;
}
$_[KERNEL]->sig_child($child->PID, "got_child_signal");
# Wheel events include the wheel's ID.
$_[HEAP]{children_by_wid}{$child->ID} = $child;
# Signal events include the process ID.
$_[HEAP]{children_by_pid}{$child->PID} = $child;
print(
"Child pid ", $child->PID,
" started as wheel ", $child->ID, ".\n"
);
}