Skip to content

Commit

Permalink
Fix for memory leak in GH #86
Browse files Browse the repository at this point in the history
  • Loading branch information
toddr committed Mar 26, 2018
1 parent efe3f36 commit 0dd47fc
Showing 1 changed file with 11 additions and 5 deletions.
16 changes: 11 additions & 5 deletions lib/IPC/Run.pm
Expand Up @@ -1135,6 +1135,12 @@ sub _debug_fd {
return fileno STDERR unless defined $cur_self->{DEBUG_FD};

return $cur_self->{DEBUG_FD};

for my $kid ( @{$self->{KIDS}} ) {
for my $op ( @{$kid->{OPS}} ) {
@{$op->{FILTERS}} = ();
}
}
}

sub DESTROY {
Expand Down Expand Up @@ -2620,15 +2626,15 @@ sub _do_kid_and_exit {
if ($@) {
_write $self->{SYNC_WRITER_FD}, $@;
## Avoid DESTROY.
POSIX::exit 1;
POSIX::_exit 1;
}

## We must be executing code in the child, otherwise exec() would have
## prevented us from being here.
_close $self->{SYNC_WRITER_FD};
_debug 'calling fork()ed CODE ref' if _debugging;
POSIX::close $self->{DEBUG_FD} if defined $self->{DEBUG_FD};
## TODO: Overload CORE::GLOBAL::exit...
## TODO: Overload CORE::GLOBAL::_exit...
$kid->{VAL}->();

## There are bugs in perl closures up to and including 5.6.1
Expand All @@ -2637,12 +2643,12 @@ sub _do_kid_and_exit {
## this may cause the closure to be cleaned up. Maybe.
$kid->{VAL} = undef;

## Use POSIX::exit to avoid global destruction, since this might
## Use POSIX::_exit to avoid global destruction, since this might
## cause DESTROY() to be called on objects created in the parent
## and thus cause double cleanup. For instance, if DESTROY() unlinks
## a file in the child, we don't want the parent to suddenly miss
## it.
POSIX::exit 0;
POSIX::_exit(0);
}

=pod
Expand Down Expand Up @@ -4304,7 +4310,7 @@ non-inheritable but we don't C<exec()> for &sub processes.
The second problem is that Perl's DESTROY subs and other on-exit cleanup gets
run in the child process. If objects are instantiated in the parent before the
child is forked, the DESTROY will get run once in the parent and once in
the child. When coprocess subs exit, POSIX::exit is called to work around this,
the child. When coprocess subs exit, POSIX::_exit is called to work around this,
but it means that objects that are still referred to at that time are not
cleaned up. So setting package vars or closure vars to point to objects that
rely on DESTROY to affect things outside the process (files, etc), will
Expand Down

0 comments on commit 0dd47fc

Please sign in to comment.