flocking issues

Austin Schutz tex at off.org
Wed May 30 18:05:44 CDT 2001

> 	while ( -f $lockfile ) {
> 		if ($timeout++ < MAX_TIMEOUT) {
> 			sleep;
> 		} else {
> 			die "Can't acquire lock on $lockfile: timed out";
> 	    	}
> 	}
>     }
>     sysopen LOCK, $lockfile, O_RDWR|O_CREAT, 0660
> 	or die "Can't open file $lockfile: $!";

	I think this code suffers from a race condition, since while
and sysopen aren't atomic. maybe try:

while ( $timeout++ <= MAX_TIMEOUT  ) {
  if( sysopen LOCK, $lockfile, O_RDWR|O_CREAT|O_EXCL, 0660 ) {
  sleep 1;
die "Can't open file $lockfile: $!" unless $got_lock;

	Using sysopen with O_EXCL seems to be an alternative method to
sharing a lock file with flock. The problem is no matter how you program it,
you may always end up with stale lock files, as noted by your code for
detecting that.
	Also, doesn't your code sleep forever since nothing is passed
to sleep()?

>     flock LOCK, LOCK_EX
> 	or die "Can't acquire lock on $lockfile: $!";

	You could put a while() loop around flock() and use
LOCK_NB. I think, though, by using sysopen with O_EXCL it's probably
not necessary to lock the file, at least so the docs indicate. I think
flock is for locking access to existing files, not necessarily locking
the creation of files.

> Will DESTROY get called if the user hits ^C, sending SIGINT?
> If not, should one use $SIG{__DIE__} or $SIG{INT} to call Demo::_unlock?

	One point here that is maybe obvious. You can't trap a KILL,
so when your program catches one it _will_ leave a stale lockfile.


More information about the Pdx-pm-list mailing list