--- Peter Scott <[EMAIL PROTECTED]> wrote:
> > A rather clever way to emulate locking is to use mkdir() and
> > rmdir().
> > Although it requires you to create a lock file, it's atomic and
> > safe.
> >
> > sub lock {
> > 1 until mkdir "$_[0].lck", 0777;
> > $locked{$_[0]}++;
> > }
One possible bug here -- it trusts that the user has kept his codeflow
and logic clean, and not done anything stupid (not that *I've* ever had
a problem like that.... ;o)
If you pass it the same lockfile name twice, your program hangs.
I'd suggest a timeout option:
sub lock {
my($name,$timeout) = @_;
$timeout = 4 unless defined $timeout; # set a default
if ($timeout) { # leaves an explicit 0 as specfied infinity
if ($timeout < 0) { # a non-blocking lock
return mkdir "$name.lck", 0777; # boolean return
} else {
my $now = time;
until ($timeout <= (time-$now)) { # watch the clock =o)
last if mkdir "$name.lck", 0777; # exit loop on success
}
}
} else {
1 until mkdir "$name.lck", 0777; # explicit zero
}
-e "$name.lck" and -d _ # test for the lockfile
? ++$locked{$name} # set as locked, return boolean true
: undef; # set return undefined (fail result)
}
This is longer and so a bit more painful to write, read, and even use,
but you can test set the timeout, or default it, or explicitly tell it
NOT to time out by passing a zero. You can also check the result to see
whether you successfully set the lock or failed (which could happen,
but isn't likely). Finally, with this you can set a non-blocking lock
by passing a negative timeout, which isn't something you need often,
but is nice sometimes.
> > sub unlock {
> > rmdir "$_[0].lck";
> > delete $locked{$_[0]};
> > }
I would also add a small error check potential here:
sub unlock {
rmdir "$_[0].lck" and delete $locked{$_[0]};
}
Now it returns a boolean that it successfully removed a lock from the
system, or didn't....again, not something you need often, but error
checking is a thing you want to do as a habit. It's a miniscule chance
that you'll fail to set a lock because the filesystem's full, but if it
happens, you want to know. It's even rarer for an unlock to fail
because somebody else just happened to accidentally delete your
directory, but again, it *might* happen, and if so, wouldn't you want
to know? =o)
Mostly, I present all this merely as elaboration to entertain myself
and hopefully help somebody somewhere get a better grasp of the
concept. Please forgive the intellectual flagellation, lol.....
> > END {
> > rmdir "$_.lck" for keys %locked;
> > }
A great example of thoroughness and forethought.
I didn't think of that. ;o>
=====
print "Just another Perl Hacker\n"; # edited for readability =o)
=============================================================
Real friends are those whom, when you inconvenience them, are bothered less by it than
you are. -- me. =o)
=============================================================
"There are trivial truths and there are great Truths.
The opposite of a trival truth is obviously false.
The opposite of a great Truth is also true." -- Neils Bohr
__________________________________________________
Do You Yahoo!?
Yahoo! Auctions - buy the things you want at great prices
http://auctions.yahoo.com/