On Saturday 12 March 2005 02:52, you wrote: > Igor Shevchenko wrote: > > Hi all, > > > > Some time ago we had a thread about starting long-running background > > processes from mp2. I've found a race condition in our last solution. The > > helper background script could be killed by apache cleanup handler before > > it had a chance to fork into background and do "setsid". Here's the > > script itself: > > > > ===start=== > > #!/usr/bin/perl -w > > use strict; > > use warnings; > > use POSIX (); > > > > chdir '/'; > > > > POSIX::setsid; > > You mean you have moved the setsid call to an earlier phase? so setsid is > called before spawn_proc_prog() has returned?
This is the first part. The second is that STDOUT is closed (by re-opening it) only after fork(), and the caller sub (exec_helper) will exit only after subprocess's STDOUT is closed. I think this should close this race condition as the caller subroutine will exit only after the background subprocess is running and is fully detached. > > exit if fork() > 0; # fork once again > > > > close STDIN; > > open STDOUT, '+>>', '/path/to/apache/error_log'; # any way to get path to > > the current error_log and pass it in from the caller as an argument or as > > an opened filehandle ? > > open STDERR, '>&STDOUT'; > > > > exec ( @ARGV ) or die "Failed to exec subprocess: [EMAIL PROTECTED]"; > > > > ===end=== > > > > Here's an updated helper subroutine: > > > > sub safe_exec { > > my $in = $apr->spawn_proc_prog ( '/path/to/exec_helper.pl', [EMAIL > > PROTECTED] ); > > > > # makes us sleep until the helper is forked into background and it's > > handlers are untied from us > > eval { read $in, my($buffer), 1024 }; > > if ( $@ ) { > > print STDERR "exec [EMAIL PROTECTED]"; > > } > > close $in; > > } > > > > I had to use this form of spawn_proc_prog to get something to wait on. > > but in the normal case where you don't need to get anything from the > sub-process the above is not needed, no? -- Best Regards, Igor Shevchenko