Tosh, On Tuesday 09 February 2010 14:21:57 Tosh Cooey wrote: > Hi after much trial and all error I am seeing that the browser > connection closing is also stopping my subprocess. >
I don't know what you are trying to achieve and I don't use Apache2::Subprocess much. What I do to fork off processes instead is this: my $close_fd=sub { use POSIX (); my %save=(2=>1); # keep STDERR undef @sa...@_} if( @_ ); opendir my $d, "/proc/self/fd" or do { warn "Cannot open directory /proc/self/fd: $!\n"; POSIX::_exit -1; # try this first to avoid buffer flushing CORE::exit -1; }; while (defined(my $fd=readdir $d)) { next unless $fd=~/^\d+$/; POSIX::close $fd unless exists $save{$fd}; } }; my $spawn=sub { use POSIX (); my ($daemon_should_survive_apache_restart, @args)=...@_; local $SIG{CHLD}='IGNORE'; my $pid; # yes, even fork can fail select undef, undef, undef, .1 while( !defined($pid=fork) ); unless( $pid ) { # child # 2nd fork to cut parent relationship with a mod_perl apache select undef, undef, undef, .1 while( !defined($pid=fork) ); if( $pid ) { POSIX::_exit 0; CORE::exit 0; } else { if( ref($daemon_should_survive_apache_restart) ) { $close_fd->($daemon_should_survive_apache_restart->{fd}); POSIX::setsid if( $daemon_should_survive_apache_restart->{survive} ); } else { $close_fd->(); POSIX::setsid if( $daemon_should_survive_apache_restart ); } if( 'CODE' eq ref $args[0] ) { my $f=shift @args; # TODO: restore %ENV and exit() behavior eval {$f->(@args)}; CORE::exit 0; } else { {exec @args;} # extra block to suppress a warning POSIX::_exit -1; CORE::exit -1; } } } waitpid $pid, 0; # avoid a zombie on some OS }; And this is how to use it: $spawn->({survive=>1}, sub { my ($n, $sleep)=...@_; for(1..$n) { warn "sleeping $sleep\n"; sleep $sleep; } warn "Done\n"; }, 10, 2 ); or $spawn-> (undef, # don't survive apache stop qw/bash -c/,'for (( i=0; i<10; i++ )); do echo "opi" >&2; sleep 2; done') The first argument to $spawn is an options hash with 2 possible options: survive=>BOOLEAN # should the subprocess survive an apache stop or not fd=>\...@list_of_open_file_descriptors_to_preserve Normally the $spawn will close all files save for STDERR. With the fd option one can preserve other files such as database connections or other. With the survive option true the child process will be the leader of a new process group. NOTES: - The $close_fd function is Linux-specific. I couldn't think of a really portable (at least across UNICES) way to get all open file descriptors of the current process. - The waitpid at the end of $spawn is not necessary under Linux since $SIG{CHLD}='IGNORE' already takes care of zombies. But other systems need it. - Keep in mind that %ENV and exit() work different under mod_perl. If you pass a subroutine this behavior remains. Torsten