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, %showcase ); ## wake up once per second while( sleep 1 ) { ## while there are showcase numbers on the queue while( $Q->pending ) { ## grab them one at a time my( $cmd, $showcasenum ) = split ':', $Q->dequeue(); ## If a timer already exists for this showcase if( exists $showcase{ $showcasenum } ) { my $when = $showcase{ $showcasenum }; ## remove the timer @{ $when{ $when } } = grep{ $_ != $showcasenum } @{ $when{ $when } }; ## and the pointer to it. delete $showcase{ $showcasenum }; ## And if this command is a delete request that's all next if $cmd eq 'del'; } ## Otherwise its a (re)add, so add the new timer ## Calculate when the timeout should occur, my $timeout = time() + $walktime; ## and add the showcase number to the hash to be dealt with at that time push @{ $when{ $timeout } }, $showcasenumber; ## And remember its there $showcase{ $showcasenum } = $timeout; } ## 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; ## remove the pointer for this showcase delete $showcase{ showcasenum }; } ## and remove the expired time from the hash delete $when{ $time }; } } }