Close. Your traditional flock will either be blocking
or non-blocking. If you only set the LOCK_EX flag, it will
block by default, therefore when you try to get the lock
it will wait indefinitely.
If this is not what you want, then you should set the
LOCK_NB flag as well, and poll at a specified interval a
specified number of times before giving up. (You can
set an alarm, but Perl's signal handling is not very
good so I would not recommend doing that.)
The portable way to get those constants is to
use Fcntl qw(:flock);
# time passes
foreach (1..10) {
$is_locked = flock(FH, LOCK_EX | LOCK_NB);
last if $is_locked; ### Or gets both flags
sleep 1;
}
# Test $is_locked here
See the longer example for the full semantics of how to do
the open, etc. (There I am locking a sentinel...)
UPDATE
In the above FH is a filehandle that has already been
opened. As for the other question, yeah that module will
solve the problem. But everything that I said about
locking will also hold when you want to start playing
games with reading and writing other kinds of data files
as well...
UPDATE 2
OK, if you want to do this explicitly for a sentinel, here
is some untested code:
use Carp;
use Fcntl qw(:flock);
sub open_sentinel {
my $lock_file = shift;
my $fh = do {local *FOO}; # Old trick
open ($fh, "> $lock_file") or die "Cannot write $lock_file: $!";
my $is_locked;
foreach (1..10) {
$is_locked = flock($fh, LOCK_EX | LOCK_NB);
last if $is_locked;
select (undef, undef, undef, 0.01);
}
return $is_locked ? $fh : undef;
}
This will wipe out the file (hence it is only useful to
use on a sentinel file). To get the lock just try to
grab. The variable will only be defined if you got the
lock, and the lock is freed when the variable is
destroyed. (So you can enter a routine, ask for a lock,
if you get it then proceed, if you don't then exit
immediately.)
The above example tries 10 times, one hundredth of a
second apart. |