Subject: | File::Pid fails to cope with stale PID files |
If a program using File::Pid does not call the remove() method, its next
invocation runs as it should, but erroneously writes a PID file with the
PID of the previous process. This means that a third invocation will
run, because the original PID no longer exists, regardless of whether
the second invocation has finished or not.
remove() might not get called due to negligent developers (like me) or
due to processes getting killed whilst running.
I have attached a test, t/set_new_pid.t and a a program t/write_pid.pl
that demonstrate this behaviour.
Tom Hukins
Subject: | set_new_pid.t |
use Test::More tests => 3;
use strict;
$^W = 1;
use File::Spec::Functions qw(catfile tmpdir);
my $program_name = catfile qw(t write_pid.pl);
my $pidfile = catfile(tmpdir(), 'write_pid.pl.pid');
my @command = ($^X, $program_name);
system(@command) == 0 or die "Could not call first $program_name: $?";
my $first_pid = read_pid();
system(@command) == 0 or die "Could not call second $program_name: $?";
my $second_pid = read_pid();
isnt $second_pid, $first_pid, 'Both processes wrote different PIDs';
unlink $pidfile;
sub read_pid {
local *PID_FH;
open PID_FH, "< $pidfile";
chomp(my $pid = <PID_FH>);
close PID_FH;
like $pid, qr/^\d+$/, "PID only contains numbers";
return $pid;
}
Subject: | write_pid.pl |
use strict;
$^W = 1;
use File::Pid ();
my $pid = File::Pid->new();
die "Service already running" if $pid->running();
$pid->write();
# Do not call $pid->remove() to behave as if this program were killed.