sub walktimer {
## The queue handle is passed in when the thread is started
my $Q = shift;
#Sleep for 180 seconds, upon completion execute SQL to change OK_OPEN back to all zero for $showcasenum
## A hash to remember when things time out.
my %when;
## wake up once per second
while( sleep 1 ) {
## while there are showcase numbers on the queue
while( $Q->pending ) {
## grab the one at a time
my $showcasenum = $Q->dequeue();
## Calculate when the timeout should occur,
## and add the showcase number to the hash to be dealt with at that time
push @{ $when{ time() + $walktime } }, $showcasenumber;
}
## find any times that have expired (earlier than now!)
for my $time ( grep{ $_ < time() } keys %when ) {
## And for each showcase number scheduled at that time
for my showcasenum ( @{ $when{ $time } } ) {
## Do your db stuff
my $dbh = DBI->connect('dbi:mysql:alarm:databasehost','username','password') or die "Connection Error: $DBI::errstr\n";
my $sql = "update Showcases set OK_OPEN=0 WHERE SC_NUM = ?";
my $sth = $dbh->prepare($sql) or die "Can't prepare $sql: $dbh->errstr\n";
$sth->execute($showcasenum) or die "SQL Error: $DBI::errstr\n";
$dbh->disconnect;
}
## and remove the expired time from the hash
delete $when{ $time };
}
}
}
####
elsif( $okopen == 1) {
#Kill the walk timer if it is running, someone opened the showcase legit
debug("Killing walking timer and starting open timer, authorized user opened showcase $showcasenum");
if( $walkthread[$showcasenum] && $walkthread[$showcasenum]->is_running() && !$walkthread[$showcasenum]->is_detached) {
$walkthread[$showcasenum]->kill('KILL')->detach();
}
$openthread[$showcasenum] = threads->create(\&opentimer, $showcasenum, $opentime, $showcasedesc);
}
##
##
elsif( $okopen == 1) {
$Qwalktimer->enqueue( $showcasenum );
}
##
##
sub walktimer {
#Sleep for 180 seconds, upon completion execute SQL to change OK_OPEN back to all zero for $showcasenum
my $showcasenum = $_[0];
debug("Launched walking timer thread for $showcasenum");
$SIG{'KILL'} = sub { threads->exit(); };
my $count = $walktime;
sleep( 1 ) while --$count; ### Wake once per second for $walktime seconds to allow the "signal handler" to respond to any pending "signals".
if( threads->is_detached()) {
threads->exit();
}
my $dbh = DBI->connect('dbi:mysql:alarm:databasehost','username','password') or die "Connection Error: $DBI::errstr\n";
my $sql = "update Showcases set OK_OPEN=0 WHERE SC_NUM = ?";
my $sth = $dbh->prepare($sql) or die "Can't prepare $sql: $dbh->errstr\n";
$sth->execute($showcasenum) or die "SQL Error: $DBI::errstr\n";
$dbh->disconnect;
debug("Walking thread for $showcasenum is expiring...");
threads->detach();
}