#!/product/perl/bin/perl -w

use POSIX qw(:signal_h :errno_h :sys_wait_h);
use IPC::Shareable;
require 5.8;

$SIG{CHLD} = \&REAPER;
sub REAPER {
    my $pid;

    $pid = waitpid(-1, &WNOHANG | &WUNTRACED);
#    $pid = waitpid(-1, &WCONTINUED);
#    $pid = waitpid(-1, &WUNTRACED);
#    $pid = waitpid(-1, 0);

    if ($pid == -1) {
        # no child waiting.  Ignore it.
    } elsif (WIFEXITED($?)) {
        print "Process $pid exited.\n";
    } else {
        print "False alarm on $pid.\n";
    }
    $SIG{CHLD} = \&REAPER;          # in case of unreliable signals
}

sub tasksExtract()
  {
#need to connect again
    my $driver = "Oracle";
    my $sid = $ENV{ORACLE_SID};
    my $port = "1521";
    my $host = "localhost";
    my $username = "scott";
    my $password = "tiger";
    my $dbh=DBI->connect($dsn, $username, $password, \%attr);
#do some stuff dbd
    print STDERR "task $$ in\n";
    sleep ($cpt);
    (tied $cpt)->shlock;
    $cpt--;
    (tied $cpt)->shunlock;


    print STDERR "task $$ out\n";
#should deconnect
    $dbh->disconnect();

    exit 0; # don't really know if other value but 0 can be used as return from a fork without stopping the father
  }

######### main #######

#create an connection
#should work with multithreaded but here it is multiprocccessed
   our $orashr : shared = '' ;
# So we don't have to check every DBI call we set RaiseError.
my $driver = "Oracle";
my $sid = $ENV{ORACLE_SID};
my $port = "1521";
my $host = "localhost";
my $username = "scott";
my $password = "tiger";

my %attr = (RaiseError => 1, AutoCommit => 0 , HandleError => Exception::Class::DBI->handler, ora_dbh_share => \$orashr);
my $dsn = "DBI:$driver:host=$host;sid=$sid;port=$port";
my $dbh= DBI->connect($dsn, $username, $password, \%attr);

#  dbh->{InactiveDestroy}=1; unuseful since there are more than one fork

$data="LLL ";
tie $cpt, 'IPC::Shareable', $data, {  create => 1, mode => 0660, destroy => 1 };
$cpt=10;
print STDERR ${cpt}."\n";
my @kids=();

$dbh->disconnect();

for (1 .. 10 )
  {
    if (!defined($kidpid = fork())) {
      # fork returned undef, so failed
      die "cannot fork: $!";
    } elsif ($kidpid == 0) {
      tasksExtract();
    } else { 
      # fork returned neither 0 nor undef, 
      # so this branch is the parent
#      print STDERR "waiting for kid $kidpid \n";#   I really want to fork many kids at the same time
#      waitpid($kidpid, 0);
      push @kids, $kidpid;		# in case we care about their pids
    }
  }

for $kidpid (@kids)
{
    $pid = waitpid($kidpid, 0);
    if ($pid == -1) {
        # no child waiting.  Ignore it.
    } elsif (WIFEXITED($?)) {
        print "Main::Process $pid exited.\n";
    } else {
        print "Main::False alarm on $pid.\n";
    }
}

print STDERR "$#kids kids :@kids,  end ${cpt}\n";
$dbh= DBI->connect($dsn, $username, $password, \%attr);
#do some stuff
$dbh->disconnect();
exit 0;
