in reply to File Locking plus delete Lockfile question

I think that a dotlock would server you better than flock here.
... my $dotlockfile = $lockfile . '.lock'; my $lfh; # create the .lock with O_EXCL (Fail if the file already exists) while (!sysopen($lfh, $dotlockfile, O_RDWR|O_CREAT|O_EXCL)) { # some timeout checking code to get out this loop ... # wait for the existing .lock to go away sleep(1); } die "Can't create $dotlockfile" unless $lfh; close($lfh); # we got our own .lock, now continue with your lock code # no need to flock here my $number_of_clients = 0; sysopen(LOCKFILE,$lockfile,O_RDWR|O_CREAT) # create if necessary or die "Can not open/create $lockfile ($!)"; eval { $number_of_clients=<LOCKFILE>||0; chomp($number_of_clients); seek(LOCKFILE,0,0) or die "Rewind error on $lockfile ($!)"; truncate(LOCKFILE,0) or die "Truncate error on $lockfile ($!)" +; if($operation='checkin') { ++$number_of_clients; ... } else { ... --$number_of_clients; } print LOCKFILE $number_of_clients,"\n"; } if($@) { warn "Exception: $@"; } close(LOCKFILE) or warn "Error closing $lockfile ($!)"; # delete if necessary (our .lock will keep others at bay) if ($number_of_clients <= 0) { unlink($lockfile) or die "Unlink error on $lockfile ($!)"; } # now release our .lock unlink($dotlockfile) or die "Unlink error on $dotlockfile ($!)";
Note: untested (I hate testing locking code)

Replies are listed 'Best First'.
Re^2: File Locking plus delete Lockfile question
by rovf (Priest) on Feb 12, 2009 at 15:41 UTC

    Is there a particular reason why you use O_EXCL in the sysopen of $dotlockfile over just opening and than doing an flock? Is there a performance penalty, or an issue of safety, of one compared to the other?

    -- 
    Ronald Fischer <ynnor@mm.st>

      The O_EXCL (Fail if the file already exists) option causes sysopen to fail if the file already exists (surprise). This lets you attempt to create the file (O_RDWR|O_CREAT), but prevents you from taking over the file if it already exists (someone else has already created it), making it an effective lock for situations where you just can't use (or trust) flock.

      Without it, one process would create the file, and the next process would simply open it again without waiting for it to be removed. In your example, the initial lock file still maintains counts of clients but since it's now being locked by the .lock file, there's no need to flock it anymore. The new .lock file restricts access to your initial lock file so clients can be sure that files don't change out from under them.

      In the "timeout checking code" bit (which I didn't include) you should probably check for things like dead lock files. If your system crashes after the .lock file has been created and before it's removed, then the file will sit around for ever locking out your application. Usually you want to check the mod time of the .lock file and remove it if it's older than some arbitrary time limit (which will depend on your application needs). You probably also want to exit the loop (or die) if you've waited too long to open the .lock file.