From 0dd47fc935ae5e8eb2db55e22cc8c2f4ed0fd804 Mon Sep 17 00:00:00 2001 From: Todd Rinaldo Date: Mon, 26 Mar 2018 17:30:06 -0500 Subject: [PATCH] Fix for memory leak in GH #86 --- lib/IPC/Run.pm | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/lib/IPC/Run.pm b/lib/IPC/Run.pm index 9bdeb43..371414c 100644 --- a/lib/IPC/Run.pm +++ b/lib/IPC/Run.pm @@ -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 { @@ -2620,7 +2626,7 @@ 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 @@ -2628,7 +2634,7 @@ sub _do_kid_and_exit { _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 @@ -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 @@ -4304,7 +4310,7 @@ non-inheritable but we don't C 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