On Friday, November 12, 2010 11:42:51 Oliver Frommel wrote: > I'd like to know if it's possible to fork an infinite loop in the > postconfig stage of the Apache lifecycle. I am trying to do it in a file > that I 'use' in the startup.pl that in turn is called by > PerlPostConfigRequire. The fork code I am using is almost the same as the > "Complete fork example" from the book, however I had to remove all > references to the Apache request $r because it is not available at this > stage. In the child process I am creating data that is exposed to other > requests via IPC::Shareable, but the requests just seem to hang. > > The code looks like this: > > startup.pl: > ... > use Datastore::Cache ( ); > ... > > Datastore/Cache.pm: > ... > if ($kid) { > ... > } else { > tie $H, 'IPC::Shareable', 'Test', {create => 1, mode => 0666}; > > while(1) { > my $rnd = rand(5); > $H = $rnd; > sleep(60); > } > } > > > As you can see, the general problem I am trying to solve is the global > creation of some data that is subject to global change (not dependent on > requests) but is available to all requests on a specific URL. Maybe there > better ways of achieving my general goal than forking?
The fork is certainly not the problem. <Perl> sub My::PostConfig { use IPC::ScoreBoard; use Apache2::ServerUtil (); if( Apache2::ServerUtil::restart_count>=2 ) { $My::sb=SB::anon 0, 0, 3; my $pid; select undef, undef, undef, 0.1 until defined($pid=fork); unless($pid) { SB::set_extra $My::sb, 2, $$; # PID SB::set_extra $My::sb, 1, 1; # running while( SB::get_extra $My::sb, 1 ) { SB::set_extra $My::sb, 0, int rand 0x7fffffff; # value sleep 1; } SB::set_extra $My::sb, 2, 0; # PID require POSIX; POSIX::_exit 0; kill 'KILL', $$; # just in case _exit() fails } } 0; } sub My::Reponse { use Apache2::RequestRec (); use Apache2::RequestIO (); my ($r)=...@_; my @l=SB::get_all_extra $My::sb; SB::set_extra $My::sb, 1, 0 if $r->args eq 'stop'; $r->content_type('text/plain'); $r->print("value=$l[0], running=$l[1], pid=$l[2]\n"); 0; } </Perl> PerlPostConfigHandler My::PostConfig <Location /test> SetHandler modperl PerlResponseHandler My::Response </Location> $ curl http://localhost/test value=380451520, running=1, pid=6265 $ curl http://localhost/test value=1301930535, running=1, pid=6265 $ curl http://localhost/test?stop value=1285288548, running=1, pid=6265 $ curl http://localhost/test value=1285288548, running=0, pid=0 I don't have IPC::Shareable here. So I took IPC::ScoreBoard. IPC::ScoreBoard can only store integer values but it does that without locking. Instead it uses atomic operations provided by the hardware. That module is quite new. So you might expect bugs. Another module that I use quite extensively is MMapDB. It might be better suited to your task. Torsten Förtsch -- Need professional modperl support? Hire me! (http://foertsch.name) Like fantasy? http://kabatinte.net