#!/usr/bin/perl
use strict;
use warnings;
use IO::Socket;
use IO::File;
use Fcntl qw/:flock/;
use Daemon;
use Web;

use constant PREFORK_CHILDREN => 5;
use constant MAX_REQUEST => 30;
use constant PIDFILE => '/tmp/prefox.pid';
use constant DEBUG => 1;

my $CHILD_COUNT = 0;

my $DONE = 0;

$SIG{INT} = $SIG{TERM} = sub { $DONE++; };

my $port = shift || 8080;
my $socket = IO::Socket::INET->new(
   LocalPort => $port,
   Reuse => 1,
   Listen => SOMAXCONN ) or die "Can't create listen socket:$!\n";

&init_server(PIDFILE);

while ( !$DONE ) {
   &make_new_child while $CHILD_COUNT < PREFORK_CHILDREN;
   sleep;
}

&kill_children;

warn "normal termination\n" if DEBUG;

exit 0;


sub make_new_child {
   my $child = &launch_child(\&cleanup_child);
   
   if ( $child ) {
      warn "launching child $child\n" if DEBUG;
      $CHILD_COUNT++;
   } else {
      &do_child($socket);
      exit 0;
   }
}

sub do_child {
   my $socket = shift;

   my $lock = IO::File->new(PIDFILE, O_RDONLY ) or die "Can't open lock file :$!\n";

   my $cycles = MAX_REQUEST;

   while ( $cycles-- ) {
      flock $lock, LOCK_EX;
      last unless my $c = $socket->accpet;
      flock $lock, LOCK_UN;

      warn "child $$ handling connection\n" if DEBUG;
      &handle_connection($c);
      close $c;
   }
   close $socket;
   close $lock;
}

sub cleanup_child {
   my $child = shift;
   $CHILD_COUNT--;
}


