Zarathustra has asked for the wisdom of the Perl Monks concerning the following question:
Greetings!
This is my first post, hope I don't do or say anything
*too* stupid... <grin>
Anyhow, I'm currently coding up a little something that
writes to mail spools. It is very likely ( in fact almost
certain ) that there will be plenty of concurrent attempts
to write to these spools - so I'm using flock. Also, I'm
syslogging the whole process and want to know when a lock
is being awaited, and I also want to make a time-out period
for waits on a lock - therefore I'm using the alarm call
and the $SIG{ALRM} trick to break out should a lock wait
take too long. .... phew ....
SO - what I'm wondering is whether I'm getting *way* too
pedantic, over-cautious and paranoid in my attempts to
safe gaurd against data corruption and race conditions.
Also, I'd like to know *just* how possible it is for
a race condition to occur between two consecutive
statements. A snippet of my current code follows
shortly - I'd very much appreciate any and all advice
concerning my logic - but first, just a couple of
scattered questions...
eval {
$SIG{'ALRM'} = sub { die "timed out!" };
alarm = 10;
flock(FH, LOCK_EX) or die "couldn't flock: $!\n";
# is there a race condition between these two points??!
alarm = 0;
};
die "$@" if $@;
What if the timeout occurs *just after* the flock is
successful and *just before* the alarm gets disabled?
Is this even remotely possible? If so, then the reason
for die'ing in the first place ( timeout grabbing the lock )
could possibly be in error... we *did* in fact grab the
lock before 10 seconds, but just barely, however the ALRM
sig still occurred before we were able to disable it ).
Now if such a race between two consecutive statements does
in fact exist, would the following buy any more certainty?
eval {
$SIG{'ALRM'} = sub { die "timed out!" };
alarm = 10;
( flock(FH, LOCK_EX) and alarm = 0 )
or die "couldn't flock: $!\n";
};
At any rate, at this time I'm going to apologize for this
behemoth post...
The following is a snippet of my code, commented to
( hopefully ) make my cluelessness and misunderstanding
completely obvious to all, please post your suggestions -
I can really use the advice... thanks!
( also, why do I need the newline in the die for the
$SIG{ALRM} sub??? and is that seek() even doing anything?
I'm trying to be certain that the file is in the exact
same condition as it was when I first opened it )
#!/usr/bin/perl -w
use Fcntl qw( :DEFAULT :flock );
$splfile = '/tmp/file.txt';
# open the backup mail spool
open(SPOOL, ">>$splfile")
or print "couldnt open: $!\n";
# try and sieze lock
unless ( flock(SPOOL, LOCK_EX | LOCK_NB) ) {
# failed initial attempt
print "$splfile busy\n";
# now try again until successful or
# 10 second alarm causes sigtrap
eval {
# define signal alarm
local $SIG{'ALRM'} = sub { die "alarm\n" };
print "waiting for lock\n";
alarm 10; # timeout in ten seconds
eval {
# wait for a green light
flock(SPOOL, LOCK_EX) or
die "could not lock $splfile: $!\n";
};
# ! potential race !
# *after* successfull lock, but
# *before* alarm unsets
alarm 0; # unset timer
if ( $@ ) {
if ( $@ eq "alarm\n" ) {
# SIG{ALRM} trapped in inner eval
die "timed out waiting for lock!\n";
} else {
# died in inner eval, flock complained
die "$@";
}
}
};
if ( $@ ) {
# race condition safegaurd
if ( $@ eq "alarm" ) {
# now unset the alarm
alarm 0;
} else {
die "$@\n";
}
}
}
print "locked $splfile\n";
# am I totally on the wrong track with
# this seek()? what if some nit-wit
# is editing the file by hand while
# we're operating on it?
seek(SPOOL, 0, 2)
or die "contention for $splfile detected: $!\n";
print "appending to mailbox\n";
print SPOOL "BAR!!\n\n";
close SPOOL;
|
|---|
| Replies are listed 'Best First'. | |
|---|---|
|
Re: race condition? - flock and $SIG{ALRM}
by JanneVee (Friar) on Sep 17, 2000 at 14:22 UTC | |
|
RE (tilly) 1: race condition? - flock and $SIG{ALRM}
by tilly (Archbishop) on Sep 17, 2000 at 20:44 UTC | |
|
(atl: flocks and processes) RE: race condition? - flock and $SIG{ALRM}
by atl (Pilgrim) on Sep 17, 2000 at 21:26 UTC | |
|
RE: race condition? - flock and $SIG{ALRM}
by Zarathustra (Beadle) on Sep 17, 2000 at 23:17 UTC | |
by atl (Pilgrim) on Sep 18, 2000 at 14:35 UTC | |
by Zarathustra (Beadle) on Sep 19, 2000 at 21:33 UTC | |
by tilly (Archbishop) on Sep 19, 2000 at 22:05 UTC | |
by Zarathustra (Beadle) on Sep 17, 2000 at 23:27 UTC |