#!/usr/bin/perl # Program to test forking and handles use lib $ENV{"PF_ROOT"}."/bin"; use lib $ENV{"PF_ROOT"}."/modules"; use strict; use DBI; use POSIX qw(:signal_h :errno_h :sys_wait_h); my $kidpid; my $iKidCount = 0; my %children; my $hashChildren; my $dbh; $hashChildren = \%children; # Get the initial database handle $dbh = get_db_connection(); if ($dbh eq "") { print("Unable to connect to database\n"); exit; } LogThis("Test program starting up, processID is $$"); while(1) { CatchWindowsKids(); $iKidCount++; LogThis("Forking child $iKidCount"); # Disconnect from database before fork LogThis("Disconnecting database connection before fork", 3); $dbh->disconnect(); undef($dbh); $kidpid = fork(); # If it didn't work at all if (! defined($kidpid)) { die("Child process failed to fork"); } # Reconnect to database $dbh = get_db_connection(); if ($dbh eq "") { print("Unable to reconnect to database\n"); exit; } # If we're the parent if ($kidpid != 0) { LogThis("Parent reconnected to database, database thread is ".$dbh->{'thread_id'}); $hashChildren->{$iKidCount} = $kidpid; LogThis("We're the parent, sleeping for 1 second"); sleep(1); next; } # Otherwise we're the child LogThis("Child reconnected to database, database thread is ".$dbh->{'thread_id'}); LogThis("Succesfully forked child $iKidCount, process ID $$"); $dbh->disconnect; undef($dbh); exit; } sub CatchWindowsKids { my $iActiveKid; my $pid; foreach $iActiveKid(keys %children) { $pid = waitpid($hashChildren->{$iActiveKid}, &WNOHANG); if ($pid != -1) { LogThis("Caught child process ".$hashChildren->{$iActiveKid}); delete($hashChildren->{$iActiveKid}); } } return; } sub LogThis { my @current_time; my $sFormattedTime; my ($sString) = @_; @current_time = localtime(time()); $sFormattedTime = sprintf("%02s:%02s:%02s", @current_time[2], @current_time[1],@current_time[0]); print "$sFormattedTime $sString\n"; return; } sub get_db_connection { my $dsn; my $dbh; $dsn = "DBI:mysql:database=pathfinder"; $dbh = DBI->connect($dsn, 'pflocal', 'pathfinder') || die "Unable to connect to database: $DBI::errstr"; return($dbh); }